为什么我可以在不提供monad的情况下调用monadic函数?

par*_*and 5 monads haskell state-monad

我认为我对Haskell Monads有很好的处理,直到我意识到这段非常简单的代码对我来说没有意义(这是来自haskell wiki关于State monad):

playGame :: String -> State GameState GameValue
playGame []     = do
  (_, score) <- get
  return score
Run Code Online (Sandbox Code Playgroud)

令我困惑的是,为什么代码允许调用"get",当提供的唯一参数是字符串时?看起来它几乎就像是从空气中汲取价值.

对我提出问题的一个更好的方法可能是,如何使用>>=和lambda而不是表示法重写此函数?我自己无法弄明白.

Dan*_*zer 7

把它写成do符号会是这样的

 playGame [] =
   get >>= \ (_, score) ->
   return score
Run Code Online (Sandbox Code Playgroud)

我们也可以写这个 fmap

 playGame [] = fmap (\(_, score) -> score) get
 playGame [] = fmap snd get
Run Code Online (Sandbox Code Playgroud)

现在的诀窍是要意识到这get是一个类似于任何其他类型的值

 State s s
Run Code Online (Sandbox Code Playgroud)

什么get将返回将无法确定,直到我们养活我们的计算,以runState或类似的,我们为我们的国家明确的初始值.

如果我们进一步简化这一点并摆脱我们所拥有的状态monad

playGame :: String -> (GameState -> (GameState, GameValue))
playGame [] = \gamestate -> (gamestate, snd gamestate)
Run Code Online (Sandbox Code Playgroud)

状态monad只是包含所有这些手动传递,GameState但你可以认为get访问我们的"功能"传递的值.