這可能有助於看到一個C m a
其實只是一個計算 - 在一個抽象的Action m
類型 - 的a
在延續傳遞風格(a -> Action m) -> Action m
表示,這樣的數據構造C
和相應的記錄選擇apply
只是語法起毛。沒有它們而沒有明確的monad實例重寫,你會得到以下等效代碼。 (請注意,類型Cnt
這裏只是的延續,而不是延續單子在Control.Monad.Trans.Cont
延續單子更像是我的CPS
類型。)
type Cnt m a = (a -> Action m) -- a continuation, not a Cont monad
type CPS m a = Cnt m a -> Action m
bind :: CPS m a -> (a -> CPS m b) -> CPS m b
cps_a `bind` a_to_cps_b = \cont_b -> cps_a (\a -> a_to_cps_b a cont_b)
或稍微詳細:
cps_a `bind` a_to_cps_b =
\cont_b -> cps_a (\a -> let cps_b = a_to_cps_b a in cps_b cont_b)
這是如何工作的?那麼,括號內的部分有一個自由變量cont_b
這是一個b
- 繼續;但是,給出了這個延續,它只是一個a
-繼續,它使用a_to_cps_b
來構造一個b
-computation(以CPS風格),它被應用於免費的cont_b
延續。簡而言之,括號中的部分是提供的a_to_cps_b
包裝在一個a
- 續。與cps_a
結合起來,我們只是運用cps_a
這a
-continuation,並將代表a
-computation通過cps_a
與產生一個b
-computation地圖a_to_cps_b
代表的組合,在CPS與自由變量b_cont
都表示。通過這個自由變量抽象給我們我們需要的CPS m b
。
我認爲這可能有助於使整個事情更容易理解,你現在可以回到原來的定義,認識到\a -> apply (f a) k
是一個真正的a
-continuation版本的f :: a -> C m b
中的自由變量k
來表達代表b
- 續。 apply m
可用於應用a
-computation m
這個a
-continuation,和我們留下的東西,從a
結合a
-computation m
與地圖f
到b
-computation,都表示在一個方面免費b
- 繼續名爲k
,我們可以使用lambda-abstract來構造所需的b
- 計算器,該計算器應該返回綁定操作符。