操纵monad堆栈

Mar*_*ota 11 monads haskell monad-transformers

如果我有单子一堆,说IO,StateError,而仅使用功能IOError.如何State从堆栈中"移除"中间monad以便我可以使用我的功能?如果订单IO,Error,State,我可以用lift匹配的类型,但我希望能够用我的功能,如果单子堆栈包含IOError在任何顺序其他可能的单子.例如:

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

someCode :: ErrorT String (StateT Int IO) ()
someCode = do
    -- I want to use fun here
Run Code Online (Sandbox Code Playgroud)

Dav*_*ani 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
Run Code Online (Sandbox Code Playgroud)