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

标签 haskell monads state-monad

我以为我已经很好地掌握了 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/

相关文章:

haskell - 您如何找到所有仅是 2、3 和 5 的幂的倍数的数字的列表?

list - Haskell处理Maybe列表

Haskell 编写 >>= 使用 >=> Monad

haskell - 在do部分中使用ErrorT转换器monad

typescript - TypeScript 中的通用类型参数和 monad

haskell - 在 Haskell 中提升 State monad 中的值

haskell - 函数式编程最好/最差解决哪些问题?

haskell - 链接状态 Monad

haskell - `:t` 和 GHCi 中的 let 表达式有什么区别