11

如果我有一堆 monad,比如说IO, StateandError和一个只使用IOand的函数Error。如何State从堆栈中“删除”中间单子以便我可以使用我的函数?如果顺序是IO, Error, State,我可以使用它来匹配类型,但是如果 monad 堆栈包含并且可能以任何顺序包含其他 monad lift,我希望能够使用我的函数。例如:IOError

fun :: ErrorT String IO ()
fun = throwError "error"

someCode :: ErrorT String (StateT Int IO) ()
someCode = do
    -- I want to use fun here
4

1 回答 1

15

只需将类型签名更改funfun :: (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
于 2012-03-08T01:25:52.790 回答