我需要使用修改功能来表达 State Monad 的 put 但是我得到了“无法推断”我的以下代码出错:
class Monad m => MonadState m s | m -> s where
get :: m s
get = modify (\s -> s)
put :: s -> m ()
put = modify $ const ()
modify :: (s -> s) -> m s
modify f = undefined --do { x <- get; put (f x) }
(*我还没有定义修改,因为我旁边的注释中的实现也返回了类似的错误,但随后返回了预期的返回类型 ms 而不是实际的返回类型 m( ))
我得到的确切错误是:
Could not deduce (MonadState m ()) arising from a use of 'modify'
from context (MonadState m s)
bound by the class declaration for 'MonadState'
at <..>
Possible fix: add an instance declaration for (MonadState m ())
In the expression: modify
In the expression: modify $ const ()
In an equation for 'put': put = modify const ()
但是我不确定这个错误试图告诉我什么以及我在这里做错了什么。如果有人能帮助我,我会非常感激!
祝你好运, Skyfe。
答案 0 :(得分:4)
const ()
会做什么,将当前状态从()
转换为s
。由于您希望此功能适用于所有状态,因此这不起作用,因为它意味着它会将状态类型从()
更改为const
。它也不会完全按照你的意愿去做。您可以使用put :: s -> m ()
put newState = modify (\currentState -> ???)
函数,但最好先编写它。我建议使用一个明确的lambda:
modify
作为旁注,您评论的modify f = do
x <- get
let newX = f x
put x
return x
实施不起作用,您真的需要
modify
但是,我建议将mtl
排除在类get
之外,因为实际上put
和{{1}}更合适。这有助于您防止循环定义。