jim*_*myt 4 monads haskell state-monad
根据State Monad的get函数提出的一个问题:
如果我跑
runState get 1
我得到了结果
(1,1)
这对我来说没问题,因为get函数将结果值设置为状态,在这种情况下状态为1.因此,(1,1)是结果.好.
但是,如果我跑
runState(do {(a,b)< - get; return a})(False,0)
我得到了结果
(假,(假,0))
这个我不明白.
get函数将结果值设置为状态并保持状态不变.所以我期待的是这样的事情
((假,0),(假,0))
与此相同
runState(do {(a,b)< - get; return b})(False,0)
结果是
(0,(假,0))
如上所述,我不再理解这一点.
所以,如果你能解释我这个奇怪的结果,那将是非常好的.;)
提前致谢
最好的祝福,
吉米
这是因为你在之后做了一些事情get,即你的return一个组成部分.忽略newtype-wrapping,
return x = \s -> (x,s)
Run Code Online (Sandbox Code Playgroud)
所以
do { (a,b) <- get; return a } === get >>= \(a,b) -> return a
Run Code Online (Sandbox Code Playgroud)
扩展到
(\s -> (s,s)) >>= \(a,b) -> (\t -> (a,t))
Run Code Online (Sandbox Code Playgroud)
并且随着它的定义(>>=)变得
\s1 -> let (r,s2) = (\s -> (s,s)) s1
in (\(a,b) -> (\t -> (a,t))) r s2
Run Code Online (Sandbox Code Playgroud)
当你以初始状态运行时(False,0),它会展开
let (r,s2) = (\s -> (s,s)) (False,0)
~> let (r,s2) = ((False,0),(False,0))
in (\(a,b) -> (\t -> (a,t))) r s2
~> in (\(a,b) -> (\t -> (a,t))) (False,0) (False,0)
~> in (\t -> (False,t)) (False,0) -- match (a,b) with (False,0)
~> in (False, (False,0))
Run Code Online (Sandbox Code Playgroud)
另一种情况return b类似.
丹尼尔的回答当然是正确和完整的,所以让我试着从不同的角度回答它并讨论可能的误解.
你期望((False,0),(False,0))被退回
runState (do{(a,b) <- get; return a}) (False, 0)
Run Code Online (Sandbox Code Playgroud)
现在要实际得到这个预期的结果,你必须写,例如,
runState (do{(a,b) <- get; return (a,b)}) (False, 0)
Run Code Online (Sandbox Code Playgroud)
(这在道德上等同于runState get (False, 0).
也许你是混乱get和runState; 后者返回一个元组,其中一个组件是计算的结果,另一个组件是最终状态.事实上,你将这个元组分开来只获得(最终)状态.get但是有一个返回值,它只是(当前)状态,仅此而已 - 无需解开.如果确实将元组拆开并仅返回a(或b),那么这将作为完整有状态计算的结果显示出来,就像您观察到的那样.
| 归档时间: |
|
| 查看次数: |
1852 次 |
| 最近记录: |