`get`如何在State monad的CPS版本中工作?

时间:2017-06-14 22:01:19

标签: haskell ocaml continuations state-monad delimited-continuations

我试图在tutorial之后理解延续。

但是,我很难理解2.10节中的以下示例:

# let get () =
    shift (fun k -> fun state -> k state state) ;;
get : unit => ’a = <fun>
我认为

state的类型为int。我没有得到的是k的类型。根据我的理解,kget ()之后捕获所有计算,并且由于我们讨论的是状态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

但是我仍然不知道为什么我需要将状态两次应用于延续。

1 个答案:

答案 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