2017-02-18 51 views
1

我通過this指南運行實現併發,我無法理解這個單子實例:窮人併發性,瞭解monad實例嗎?

data Action m = Atom (m (Action m)) | Fork (Action m) (Action m) | Stop 

newtype C m a = C {apply :: (a -> Action m) -> Action m} 

instance Monad (C m) where 
m >>= f   = C $ \k -> apply m(\a -> apply (f a) k) --? 
return x  = C $ \k -> k x 

我明白延續單子的基本用途,但我掙扎破譯這是怎麼回事在這個聲明?

回答

4

這可能有助於看到一個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_aa -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與地圖fb -computation,都表示在一個方面免費b - 繼續名爲k,我們可以使用lambda-abstract來構造所需的b - 計算器,該計算器應該返回綁定操作符。