理解 State Monad 中的状态参数

Understanding the state argument in the State Monad

我正在努力思考 State Monad,但我不明白以下内容:

鉴于 return(>>=) 的实施,当您说 State $ \s ->.... 时,s 来自哪里?我的意思是,当您开始执行 >>= ... >>= 时,这是否意味着您必须以某种方式在链的开头某处提供该初始参数?

newtype State s a=State { runState::s->(a,s) }

 instance Monad (State s) where
        return a=State $ \s->(a,s)
        (>>=) m g=State $ \s -> let (a,s')= runState m s in
                                   runState (g a) s'

(>>=) 中你说 State $ \s -> runState m s,而我不明白 什么时候 是初始的 (\s -> ...) argument(带有 REAL argument) 调用?

有人可以解释一下吗?

稍后编辑:

谁能告诉我如何设置 initial 状态,假设它是否需要使用 getLine 获取值?

main::IO()
main=do
  argument<-getLine
  --how do i set initial state with argument?
  m >> f1 >> f2 >> f3

when you say State $ \s ->...., where does s come from ?

来自调用,当runState提供初始状态值给state-monadic 值,运行 它描述的组合计算:

st = do { x <- get ; return (x+1) }

x = runState st 0    -- x is (1,0)

我还感觉到您可能存在另一个误解:您写道:“什么时候 是初始 (\s -> ...) argument 调用的?”没有 "initial" lambda:lambda 都嵌套在里面!

do { a <- as; b <- bs; c <- foo b; return c }

翻译为

as >>= (\a -> bs >>= (\b -> foo b >>= (\c -> return c)))

所以它不是 "initial",而是一个组合的 all-enclosing lambda,它是用初始状态调用的!

然后会调用

let (a,s1) = runState as s0

等"initial" asdo 块中。

do 块不执行 任何有状态计算 - 它只是将一些较小的有状态计算组装成一个较大的有状态计算。在do级别,实际状态不存在。

如果调用 monad "a stateful computation" 会更简单,甚至可能更准确。或者 "a function that takes state of type S and returns another state of the same type alongside its actual result"。那么你可以想象 >>= 为 "combines two functions of the aforementioned type into one, such that the state returned by the first one is be passed as a parameter to the second one".

State 只是 s -> (a, s) 类型函数的包装器。 runState 实际上 "run" 什么都没有;它只是返回由 State 构造函数包装的函数。但是,您可以将 runState 与函数的 ($) 运算符进行比较。

($)             f  x = f x
runState (State f) s = f s

这使得 (=<<) = flip (>>=) 类似于 (<<<) = (.);它不是采用两个函数并返回第三个函数,而是采用一个函数(即 returns 一个 State)和一个 State 并产生第二个 State

但是,我们将直接比较 (>>=)(>>>) = flip (.),以便更好地对齐类型。 (同样,您可以将 (.)(=<<) 进行比较。)

-- f :: t -> a
-- g ::      a -> b
f >>> g =         \t -> let a       = ($)      f     t
                        in            ($)      g     a
-- m :: State s a
-- g ::         a -> State s b
m >>= g = State $ \s -> let (a, s') = runState m     s
                        in            runState (g a) s'