使用do编写IO Monads

时间:2013-11-15 12:45:51

标签: haskell io monads

我在Reader Monad中有代码,以便将文件句柄作为读取器链中的不可见参数传递。

在writeMail中,我正在尝试创建一个Reader,当使用runReader运行时,它会产生IO()输出,这个输出本身就是IO monads链的结果

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

但是我发现只有IO链中的最后一个,即wmb,才会在控制台上打印。

任何人都可以看到我应该做什么来获取wmh,然后wmb打印?

2 个答案:

答案 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打印“foo”和“bar”。所以我怀疑错误在writeMailHeaders

答案 1 :(得分:2)

你需要的不仅仅是一个读者,而是ReaderT monad变换器,IO作为基础monad。

由于您的示例不完整,我做了一些更改以显示您的选项:

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"