我正在學習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