haskell State Monad表示使用修改

时间:2014-10-14 21:14:39

标签: haskell state monads

我需要使用修改功能来表达 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。

1 个答案:

答案 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}}更合适。这有助于您防止循环定义。