[英]How does `get` work in the CPS version of the State monad?
我试图在本教程后继续理解延续。
但是,我很难理解2.10节中的以下示例:
# let get () =
shift (fun k -> fun state -> k state state) ;;
get : unit => ’a = <fun>
我认为state
是int
类型。 我没有得到的是k
的类型。 根据我的理解, k
捕获随后在get ()
之后的所有计算,并且因为我们讨论的是状态monad,所以k
是合理的,表示将通过取一个int
继续的计算,因此
k : int => 'a
但是从代码来看,它似乎没有这样做,它第二次需要state
,这实际上意味着:
k : int => int => 'a
但是我没有得到第二个来自哪里,并且在哪种意义上get
是type unit => 'a
而不是unit => int => 'a
?
与实际状态monad实现相比,混乱增加了更多:
newtype StateT s m a = StateT { runStateT :: s -> m (a,s) }
即状态转换表示为从状态到结果和状态元组的函数,这与我的第一个理解相匹配。
任何人都可以领先吗?
其次,我怎么来实现get
这里使用Haskell的Control.Monad.Trans.Cont
? 我在安慰类型系统方面遇到了问题。
UPDATE
看来我得到了第二个:
Prelude Control.Monad.Trans.Cont> let get () = shift $ \k -> return $ \i -> k i i
但我仍然不明白为什么我需要将状态两次应用于延续。
你在state
上应用k
两次,因为第一个对应于get ()
的结果(我们希望get
的效果是检索当前状态并将其作为结果返回),第二个对应于在get
之后传递状态(因为get
不会改变状态,与get
之前的状态相同)到下一个有状态计算。
换句话说,由于状态monad是State sa ~ s -> (a, s)
,它的CPS版本是State sra ~ s -> (a -> s -> r) -> r
,所以对于get : State ss
,因为a ~ s
,延续将是s -> s -> r
类型s -> s -> r
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.