我在 Haskell Web 项目中遇到了错误Ambiguous type variable
。
相关代码是
--- Other import statements
import qualified Model as Model
---------- HTTP Handlers
needItem db user itemName = do
Model.changeItemStatus db user itemName Model.Need
listItems db user
gotItem db user itemName = do
Model.changeItemStatus db user itemName Model.Got
listItems db user
newItem db user itemName comment count = do
Model.insertItem db user itemName comment count
listItems db user
listItems db user = do
lst <- Model.listItems db user
resOk lst
--- rest of the program
这些错误专门抱怨insertItem
and changeItemStatus
,这两个都是acid-state
查询函数
insertItem db name itemName comment count = withAccount db name newItem
where item = Item { itemName = itemName, itemComment = comment, itemCount = count, itemStatus = Need }
newItem account = update' db $ NewItem account item
-- other stuff
changeItemStatus db name itemName status = withAccount db name cItem
where cItem account = withItem account itemName
(\i -> update' db $ ChangeItem account $ i { itemStatus = status})
withAccount
并且withItem
是帮助我处理Maybe
来自数据库的返回值的辅助函数。它们被定义为
withAccount :: MonadIO m => AcidState GoGetDB -> String -> (Account -> a) -> m (Maybe a)
withAccount db name fn = do
maybeAccount <- query' db $ AccountByName name
return $ do acct <- maybeAccount
return $ fn acct
withItem :: Account -> String -> (Item -> a) -> Maybe a
withItem account itemName fn = do
item <- getOne $ (accountItems account) @= itemName
return $ fn item
好的,那么现在。
我已经多次阅读Happstack 速成课程中的 AcidState 文档,但没有多大帮助;他们直接在其响应生成函数中使用查询
- 我试过了,得到了同样的
Ambiguous type variable
错误,除了指向query'
调用iteslf, - 我真的不想这样做,因为那会迫使我混合我的模型/控制器代码和
- 对我的特殊情况没有帮助,因为它没有向我显示调用
query'
或update'
将要调用的函数的具体返回类型是什么(它们的函数都是AcidState DBName -> ServerPart Response
,因为它们直接生成响应)。
我试图通过使用表达式的片段来组合类型签名insertItem
,但每次尝试都给了我我认为更糟糕的错误。changeItemStatus
:t
No instance for (MonadIO m1)
我还不是一个特别熟练的 Haskeller,所以我觉得我唯一可以尝试的另一件事就是return $
在这个地方撒上随机 s,但这听起来不太可能真正解决问题或教学我什么。
我试图实现的一般概念是:“对数据库进行此更改,然后返回当前用户的相关元素的(可能更改的)列表”。
关于我接下来应该尝试什么,或者我具体哪里出错的任何提示?我是否以完全错误的方式思考这个问题?我是否可以就该主题查阅其他文件?
PS。我已经包含了我认为上面所有相关的代码,但是如果你想查看完整的源代码,它就在这里和这里。
编辑:完整类型错误
/home/inaimathi/projects/goget/goget.hs:31:3:
Ambiguous type variable `m2' in the constraint:
(Control.Monad.IO.Class.MonadIO m2)
arising from a use of `Model.changeItemStatus'
Probable fix: add a type signature that fixes these type variable(s)
In a stmt of a 'do' block:
Model.changeItemStatus db user itemName Model.Need
In the expression:
do { Model.changeItemStatus db user itemName Model.Need;
listItems db user }
In an equation for `needItem':
needItem db user itemName
= do { Model.changeItemStatus db user itemName Model.Need;
listItems db user }
/home/inaimathi/projects/goget/goget.hs:35:3:
Ambiguous type variable `m1' in the constraint:
(Control.Monad.IO.Class.MonadIO m1)
arising from a use of `Model.changeItemStatus'
Probable fix: add a type signature that fixes these type variable(s)
In a stmt of a 'do' block:
Model.changeItemStatus db user itemName Model.Got
In the expression:
do { Model.changeItemStatus db user itemName Model.Got;
listItems db user }
In an equation for `gotItem':
gotItem db user itemName
= do { Model.changeItemStatus db user itemName Model.Got;
listItems db user }
/home/inaimathi/projects/goget/goget.hs:39:3:
Ambiguous type variable `m0' in the constraint:
(Control.Monad.IO.Class.MonadIO m0)
arising from a use of `Model.insertItem'
Probable fix: add a type signature that fixes these type variable(s)
In a stmt of a 'do' block:
Model.insertItem db user itemName comment count
In the expression:
do { Model.insertItem db user itemName comment count;
listItems db user }
In an equation for `newItem':
newItem db user itemName comment count
= do { Model.insertItem db user itemName comment count;
listItems db user }