我以为我已经很好地掌握了 Haskell Monads,直到我意识到这段非常简单的代码对我来说毫无意义(这是来自 haskell wiki about the State monad ):
playGame :: String -> State GameState GameValue
playGame [] = do
(_, score) <- get
return score
令我困惑的是,当提供的唯一参数是字符串时,为什么允许代码调用“get”?看起来几乎就像是凭空拉出值(value)一样。
对我来说,提出这个问题的更好方法可能是,如何使用 >>=
和 lambda 而不是 do 表示法重写这个函数?我自己无法弄清楚。
最佳答案
将其脱糖为 do
表示法看起来像
playGame [] =
get >>= \ (_, score) ->
return score
我们也可以用fmap
来写这个
playGame [] = fmap (\(_, score) -> score) get
playGame [] = fmap snd get
现在的技巧是要认识到 get
是一个与任何其他具有该类型的值一样的值
State s s
在我们将计算提供给 runState
或类似的地方(为状态提供显式起始值)之前,无法确定 get
将返回什么。
如果我们进一步简化并摆脱我们所拥有的状态单子(monad)
playGame :: String -> (GameState -> (GameState, GameValue))
playGame [] = \gamestate -> (gamestate, snd gamestate)
状态单子(monad)只是包装了 GameState
的所有手动传递,但您可以将 get
视为访问我们的“函数”传递的值。
关于haskell - 为什么我可以在不提供 monad 的情况下调用 monadic 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22841899/