user47376
user47376

Reputation: 2273

Haskell MTL: How to exit the monad and get the value within it?

I know how to use functions from each monad inside a do block. But once i'm finished how do I run the computation and get the result?

run :: (MonadError Error m, MonadState State m) => m Int -> Int
run = ???

Upvotes: 2

Views: 392

Answers (1)

Alec
Alec

Reputation: 32319

The whole point of mtl is that you don't specify your concrete monad transformer stack - you just specify that it has to handle errors and hold state.

However, once you actually want to run this action, you do need to tie yourself down to a particular monad transformer stack. That stack will inform how you can "run" your monadic action. In your case, it looks like you probably want to go with ExcepT Error (State State):

action :: (MonadError Error m, MonadState State m) => m Int
action = undefined

runAction :: State ->           -- initial state
             Either Error Int   -- account for possibility of error
runAction initialState = evalState (runExceptT action) initialState

Note that this isn't the only choice of a concrete stack you could have made. In fact, you could even swap the order of the State and Except and choose StateT State (Either Error) as your monad!

runAction :: State ->           -- initial state
             Either Error Int   -- account for possibility of error
runAction initialState = evalState action initialState

The fact that mtl says nothing about the order of monads in your stack is one of its shortcomings (and one of the reasons why some people prefer to just stick with transformers).

Upvotes: 6

Related Questions