【发布时间】:2019-01-07 02:17:43
【问题描述】:
我是 Haskell 的新手,但我仍然无法弄清楚 do 块是如何与 monad 相关的。
例如,我返回 Integer 的这个 do 块考虑 IO Integer
getNumber :: IO Integer -- A IO monad of type Integer
getNumber = return 100
但是例如有一个返回可能用户的do块,do块的类型是Maybe User但我期待IO (Maybe User)
persistUser :: IO (Maybe User)
persistUser = do return Just(User { userId = 100, userName = "Paul" })
相反,代码甚至没有编译。而且我无法计算错误编译。
• Couldn't match type ‘a0 -> Maybe a0’ with ‘IO (Maybe User)’
Expected type: User -> IO (Maybe User)
Actual type: User -> a0 -> Maybe a0
• The function ‘return’ is applied to two arguments,
but its type ‘(a0 -> Maybe a0) -> User -> a0 -> Maybe a0’
has only three
In a stmt of a 'do' block:
return Just (User {userId = 100, userName = "Paul"})
In the expression:
do { return Just (User {userId = 100, userName = "Paul"}) }
似乎期待用户作为输入,但甚至添加签名
User -> IO (Maybe User) 或 User IO (Maybe User) 不起作用。
也许我误解了文档中的某些内容。对此进行一些澄清会很棒!
问候。
【问题讨论】:
-
注意错误提示:“函数‘return’应用于两个参数”。您正在使用参数 1)
Just和 2)User{...}调用return。这不是你想要的。 -
顺便说一句,我发现“函数
return应用于两个参数,但它的类型只有三个”非常有趣。我想知道导致这种情况发生的错误消息逻辑是什么。 -
@DanielWagner 看起来想法是如果参数的数量是固定的(例如,
fst head [x]),就会出现合理的错误。但是由于return是多态的,return f x“可能”有正确数量的参数,所以我们偷偷检查“参数是否太多”检查。然后我们进入假设参数不匹配计数意味着太少的代码。
标签: haskell