我正在学习monad变形金刚,我读了this SO贴子,关于如何避免lift
s。Haskell:为什么这个monad转换是错误的?
我的想法是,MonadIO
的单子,其中IO
可以嵌入,并MonadWriter w
的单子,其中WriterT w
可以嵌入。所以我编写了下面的代码(读取,累积和记录数字,直到我们得到一个零),其中一个使用明确的lift
的工作版本在注释中。但GHC抱怨。我究竟做错了什么?
{-# LANGUAGE FlexibleContexts #-}
import Control.Monad.IO.Class
import Control.Monad.Writer.Class (MonadWriter)
import Control.Monad.Trans.Reader
import Control.Monad.Trans.Writer
-- f :: ReaderT Int (WriterT [String] IO) Int
-- m1 = ReaderT, m2 = WriterT
f :: (MonadWriter [String] m1, MonadIO m2) => m1 (m2 (IO Int))
f = do
s <- liftIO getLine
tell ["Input: " ++ s] -- lift $ tell ["Input: " ++ s]
let i = read s :: Int
if i == 0
then ask
else local (+i) f
main = do
rst <- runWriterT $ runReaderT f 0
print rst
如何GHC抱怨吗? (总是添加错误信息) – Zeta