我是一个 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/