Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Manipulating the monad stack

If I have a stack of monads, say IO, State and Error, and a function that only uses IO and Error. How would one go about "removing" the middle State monad from the stack so I can use my function? If the order was IO, Error, State, I could use lift to match the types, but I want to be able to use my function if the monad stack contains IO and Error and possibly other monads in whatever order. For example:

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

someCode :: ErrorT String (StateT Int IO) ()
someCode = do
    -- I want to use fun here
like image 205
Marek Sapota Avatar asked Mar 08 '12 00:03

Marek Sapota


1 Answers

Just change the type signature of fun to fun :: (MonadError String m, MonadIO m) => m (). It will then be usable for any monad stack that have a String Error, and can perform IO (such as ErrorT String (StateT Int IO)).

Eg:

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
like image 170
David Miani Avatar answered Oct 11 '22 15:10

David Miani