我尝试使用MonadIO
类中的liftIO
函数在State
monad中打印:
import Control.Monad.State
import Control.Monad.IO.Class
import Control.Applicative
facHelper :: Integer -> State Integer ()
facHelper 0 = pure ()
facHelper n = do
currentState <- get
liftIO $ putStrLn $ "n = " ++ show currentState
modify (*n)
facHelper (n-1)
factorial :: Integer -> Integer
factorial n = snd (runState (facHelper n) 1)
main :: IO ()
main = print $ factorial 6
字符串
但是,我得到了错误:
没有因使用“liftIO”而产生的(MonadIO Data.Functor.Identity.Identity)示例
如果我查找MonadIO
类:
我看到一个例子:
MonadIO m => MonadIO (StateT s m)
型
还可以看到State s
是类型别名,
type State s = StateT s Identity
型
所以,原则上,我可以使用liftIO
和State
。问题在哪里?
1条答案
按热度按时间muk1a3rh1#
如果你想做
IO
,那么IO
必须在你的monad Transformer堆栈的底部。下面是通常的mtl
修复方法:字符串
它使用
StateT Integer IO
而不是State Integer
(即StateT Integer Identity
)。如果你对你的方法出了什么问题的机械细节感到好奇:
1.我要
MonadIO (State s)
1.我有
type State s = StateT s Identity
,所以想要MonadIO (StateT s Identity)
1.我有
MonadIO m => MonadIO (StateT s m)
,更具体地说,我有MonadIO Identity => MonadIO (StateT s Identity)
,因此需要MonadIO Identity
1.我不(也不能明智地)拥有
MonadIO Identity