我是一个 Haskell 初学者并试图理解 StateMonad 的这个定义,特别是绑定(bind)操作。它取自 Generalising Monads to Arrows 第 4 页。

instance Monad (StateMonad s) where
     return a = SM (\s -> (a, s))
     x >>= f = SM (\s -> let
                             SM x' = x
                             (a, s') = x' s
                             SM f' = f a
                             (b, s'') = f' s'
                         in (b, s''))

最佳答案

首先你需要了解 >>= 的类型;我会假设你这样做,因为它在该论文的第 2 页上,并且你已经通过了。

如果我们定义 runState ,则 bind 的定义可能更容易理解。

newtype SM s a = SM (s -> (a, s))

runState ::  SM a  -> s -> (a, s)
runState    (SM f)    s =  f s
-- this is equivalent to
-- runState (SM f) =  f
runState 通过提取转换状态的函数 f 并将其应用于初始状态 s 来运行状态 monad。函数 f 返回一个 (a, s) 类型的元组。元组包含依赖于状态的值(a 类型)和一个新状态(s 类型)。以下是等价的
let (a, s') = runState x s
in ...

let SM x' = x
    (a, s') = x' s
in ...

这两个函数都从 x' 中提取了状态如何转换的函数 x ,然后将其应用于初始状态 s 。结果元组 (a, s') 保存状态相关值 a 和新状态 s'

我们可以用 SM 替换 >>= 定义中的 runState 模式匹配。
 x >>= f = SM (\s -> let
                         (a, s')  = runState x     s
                         (b, s'') = runState (f a) s'
                     in  (b, s''))

现在我们将逐一介绍它。

Bind 使用依赖于某些初始状态 StateMonad 的函数构造一个新的 s 。它返回一个状态相关的值 b 和一个新的状态 s'' :
 x >>= f = SM (\s -> let
                         ...
                     in  (b, s''))

通过使用初始状态 a 运行状态 monad s' 来计算状态相关值 x 和新状态 s :
                     let
                         (a, s')  = runState x     s

新的状态 monad f a 由用户提供的函数 f 和状态相关值 a 确定。第二个状态 monad 以中间状态 s' 运行。它计算另一个状态相关值 b 和一个最终状态 s''
                         (b, s'') = runState (f a) s'

第二个状态相关值 b 和最终状态 s'' 是为新的 StateMonad 构造的函数返回的值。

关于haskell - 理解 StateMonad,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38821865/

10-11 14:46