我在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打印?
答案 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"