如果我有一堆monad,请说IO
,State
和Error
,以及只使用IO
和Error
的函数。如何从堆栈中“移除”中间State
monad以便我可以使用我的函数?如果订单是IO
,Error
,State
,我可以使用lift
来匹配类型,但如果monad堆栈包含,我希望能够使用我的函数IO
和Error
以及可能的其他monad以任何顺序排列。例如:
fun :: ErrorT String IO ()
fun = throwError "error"
someCode :: ErrorT String (StateT Int IO) ()
someCode = do
-- I want to use fun here
答案 0 :(得分:15)
只需将fun
的类型签名更改为fun :: (MonadError String m, MonadIO m) => m ()
即可。然后它可用于任何具有String
错误的monad堆栈,并且可以执行IO(例如ErrorT String (StateT Int IO)
)。
例如:
fun :: (MonadError String m, MonadIO m) => m ()
fun = do
liftIO $ putStrLn "in fun"
throwError "error"
someCode :: ErrorT String (StateT Int IO) ()
someCode = do
fun
-- whatever you want