理解 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" as
在 do
块中。
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'
我正在努力思考 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 doess
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" as
在 do
块中。
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'