我试图在tutorial之后理解延续。
但是,我很难理解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
的类型为unit => 'a
而不是unit => int => 'a
?
与实际状态monad实现相比,混乱增加了更多:
newtype StateT s m a = StateT { runStateT :: s -> m (a,s) }
即。状态转换表示为从状态到结果和状态元组的函数,这符合我的第一个理解。
任何人都可以领先吗?
其次,我如何使用Haskell get
在这里实现Control.Monad.Trans.Cont
?我在安慰类型系统方面遇到了问题。
更新
我似乎得到了第二个:
Prelude Control.Monad.Trans.Cont> let get () = shift $ \k -> return $ \i -> k i i
但是我仍然不知道为什么我需要将状态两次应用于延续。
答案 0 :(得分:3)
您在k
上应用state
两次,因为第一个对应get ()
的结果(我们希望get
的效果是检索当前状态并返回它作为结果)而第二个对应于在get
之后传递状态(因为get
没有改变状态,因为它与get
之前的状态相同)到下一个有状态计算。
换句话说,由于状态monad为State s a ~ s -> (a, s)
,因此其CPS版本为State s r a ~ s -> (a -> s -> r) -> r
,因此对于get : State s s
,因为a ~ s
,延续将是一个函数类型为s -> s -> r
。