2013-11-15 39 views
0

我在Reader Monad中有代碼,以便將文件句柄作爲不可見參數傳遞給Reader鏈。使用do編寫IO Monads

在writeMail,我試圖創建一個閱讀器,其中,使用runReader運行時,產生一個IO()輸出其本身IO單子的鏈的結果

writeMail :: Reader Handle (IO()) 
writeMail mail = do 
wmh <- writeMailHeaders mail 
wmb <- writeMailBody mail 
return $ wmh >>= \_ -> wmb 

但是我發現只有IO鏈中的最後一個,即wmb,在控制檯打印。

任何人都可以看到我應該做什麼來獲得wmh,然後wmb打印?

回答

2

您需要的不僅僅是一個讀卡器,而是一個ReaderT monad變壓器,其中IO作爲基準單元。

由於您的例子是不完整的,我做了一些修改,以顯示你的選擇:

import Control.Monad.Reader 

writeMail :: ReaderT Handle IO() 
writeMail = do 

    -- Here's how you get your handle to further do something to it: 
    handle <- ask 

    -- Here's how you do the IO actions. 
    -- Notice the `lift` function, 
    -- which allows us to run actions of the base monad, 
    -- which in that case is `IO`. 
    lift $ do 
    print "bla bla" 
    print "bla" 
+1

我不是OP,但我認爲基本使用monad變壓器只是爲我點擊。謝謝一堆。 – kqr

+0

是的。我記得同樣的感覺。直到某個時候,對於我來說,這一切都是巫術,當一個簡單的實現是通過「點擊」來實現的。 –

3

有了簡單的例子:

module Read where 

import Data.Functor.Identity 

write :: Monad m => m (IO()) 
write = do 
    a <- return $ putStrLn "foo" 
    b <- return $ putStrLn "bar" 
    return $ a >> b 

main :: IO() 
main = runIdentity write 

main版畫既 「富」 與 「酒吧」。所以我懷疑這個錯誤在writeMailHeaders