“类型变量不明确”在 Haskell Yesod 中使用 Persistent
Posted
技术标签:
【中文标题】“类型变量不明确”在 Haskell Yesod 中使用 Persistent【英文标题】:"Type variable is ambiguous" with Persistent in Haskell Yesod 【发布时间】:2013-12-11 06:31:38 【问题描述】:我正在尝试将 Persistent 与 Yesod 一起使用,以从我的数据库中的表中获取所有字段键的列表。我的访问器代码如下:
getMapList :: Handler [Text]
getMapList = runDB $ do
dbList <- selectList [] []
return (map getMapName dbList)
where getMapName (Entity (Key (PersistText mapName)) _) = mapName
注意这是一个游戏:这里的“地图”是游戏意义上的地图,而不是 Haskell 意义上的地图。
我收到以下错误,这表明类型推断引擎无法根据我使用的数据库后端确定我的类型。
Handler/Create.hs:101:13:
Couldn't match type `PersistEntityBackend t0'
with `persistent-1.2.3.0:Database.Persist.Sql.Types.SqlBackend'
The type variable `t0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Expected type: PersistMonadBackend (SqlPersistT (HandlerT App IO))
Actual type: PersistEntityBackend t0
In a stmt of a 'do' block: dbList <- selectList [] []
In the second argument of `($)', namely
`do dbList <- selectList [] [];
return (map getMapName dbList) '
In the expression:
runDB
$ do dbList <- selectList [] [];
return (map getMapName dbList)
有人知道如何解决这个问题吗?我需要在类型签名中添加什么才能正确地进行类型检查?谢谢!
编辑:我的模型是这样定义的:
GameMap
mapName Text
mapCode Text
UniqueGameMap mapName
deriving Typeable
【问题讨论】:
【参考方案1】:我认为您需要添加过滤器类型签名,该签名基于您在其他地方定义的表(我不确定您是否试图避免在某处输入列名......我不确定如果可能的话)。
这对你有用吗?如果表定义为-
share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
KingsLadiesInWaiting
name String
skillLevel Int
deriving Show
|]
只需添加-
getMapList :: Handler [T.Text]
getMapList = runDB $ do
dbList <- selectList ([]::[Filter (KingsLadiesInWaitingGeneric backend)]) []
return (map getMapName dbList)
where getMapName (Entity (Key (PersistText mapName)) _) = mapName
当我这样做时,它编译了。
这应该是一个有趣的游戏!
【讨论】:
我尝试使用 GameMapGeneric 而不是 KingsLadiesInWaitingGenerc,但出现以下错误:不在范围内:类型构造函数或类“GameMapGeneric”。有什么特别需要我进口的吗?我正在使用一个脚手架站点,所以我把它分散在一堆文件中,我的处理程序都在他们自己的文件中。 当您运行“yesod init”时,它应该已经创建了一个名为Model.hs 的文件,您需要将该文件与该函数一起导入到该文件中。实际模型应该在 config/models 中,因此您还可以验证“GameMap”表是否存在。 我仍然收到错误,当我执行“导入模型(GameMapGeneric)”时,我得到“模块'模型'不导出'GameMapGeneric'”。有什么想法吗?非常感谢到目前为止的所有帮助。 好/坏消息....好消息是 - 我使用“ghc --show-iface Model.hi”检查了 Model.hs 创建的数据类型,并能够找到创建的实际类型(它只是表名,末尾没有 Generic 一词)。它跑了。坏消息是,输出不是您预期的那样。它不是列名,而是列值。我可能会再玩一些,并尝试寻找是否有其他方法来获取列名。 搞定了,这有点小技巧,但我在选择过滤器列表中添加了一个微不足道的条件,而不是 [],这足以让类型检查器弄清楚。以上是关于“类型变量不明确”在 Haskell Yesod 中使用 Persistent的主要内容,如果未能解决你的问题,请参考以下文章
Haskell,Yesod和Keter - 我如何定期(每5分钟)运行一次例行程序?
当用户不在 Yesod/Haskell 的数据库中时如何重定向到特殊页面