5

我试图在本教程之后理解一般的延续。

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

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

stateint我想的类型。我不明白的是k. 根据我的理解,k捕获所有计算随后发生在 之后get (),并且由于我们正在谈论一个状态单子,k因此可以合理地表示将通过一个 继续进行的计算int,因此

k : int => 'a

但从代码来看,它似乎并没有这样做,它需要state第二次,这实际上意味着:

k : int => int => 'a

但我不知道第二个是从哪里来的,在哪种意义上get是类型unit => 'a而不是unit => int => 'a

与实际的 state monad 实现相比,混乱增加了更多:

newtype StateT s m a = StateT { runStateT :: s -> m (a,s) }

即状态转换表示为从状态到结果和状态的元组的函数,这符合我的第一个理解。

任何人都可以领导吗?

其次,我应该如何get使用 Haskell 在这里实现Control.Monad.Trans.Cont?我在安慰类型系统时遇到问题。


更新

看来我得到了第二个:

Prelude Control.Monad.Trans.Cont> let get () = shift $ \k -> return $ \i -> k i i

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

4

1 回答 1

4

您申请kstate两次,因为第一个对应于get ()(我们希望get的效果是检索当前状态并将其作为结果返回) 的结果,第二个对应于在get(which, 因为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,延续将是 type 的函数s -> s -> r

于 2017-06-15T01:25:10.953 回答