5

我試圖瞭解下面這個tutorial的延續。`get`如何在State monad的CPS版本中工作?

然而,我有困難,瞭解在節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

相比於實際狀態單子實現中,混亂增加了更多:

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

即狀態轉換表示爲從狀態結果和狀態的元組,其中我的第一理解相匹配的功能。

任何人都可以領先?

其次,我該如何在這裏使用Haskell的Control.Monad.Trans.Cont來實現get?我遇到了安慰類型系統的問題。


UPDATE

看來我拿到了第二個:

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

但我仍然不知道爲什麼我需要兩次運用狀態的延續。

+0

@Bergi它實際上被稱爲OchaCaml。我正在學習教程,但我不認爲使用的語言會影響這種情況下對概念的理解。 – HuStmpHrrr

回答

3

state申請k兩次,因爲第一個對應於get()結果(我們希望get的效果要檢索當前狀態,並恢復它的結果),第二個對應於合格後狀態get(因爲get不改變狀態,與get之前的狀態相同)到下一個有狀態計算。

換句話說,由於狀態單子是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類型的函數。

+0

這是我沒有得到的主要部分。現在只要通過現狀就可以延續下去嗎?我也不明白如何從狀態monad版本升級到cps版本。 – HuStmpHrrr

+0

另外我怎樣才能知道延續的類型只是通過查看代碼?我應該看哪個部分,洞還是洞? – HuStmpHrrr

+0

想象一下,如果'get'的結果應該是當前狀態+ 1(例如將其固定到'State Int'),你會想要傳遞什麼。隨後的狀態仍然與傳入狀態相同,但結果會有所不同。所以你需要傳遞'state + 1'作爲結果參數,'state'作爲繼續的新狀態參數。 – Cactus