Riccardo T.
Riccardo T.

Reputation: 8937

How to nicely evaluate nested StateT and ErrorT monads?

I have two type declarations for control structures at different levels in a program. The bottom one is the Agent, a StateT with IO capabilities. The second one is another StateT with Agent capabilities, and the third one (Plan) is an ErrorT.

type Agent = StateT AgentState IO
type Plan = ErrorT PlanError (StateT PlanState Agent)

What is the best way to evaluate a Plan? I wrote the following code, but it is not very handful because there are loads of nested runStateT and runErrorT calls.

foo :: Plan ()
defaultAgentState :: AgentState
runStateT (runStateT (runErrorT foo) (PlanState 0)) defaultAgentState

Is there something simpler/nicer?

Upvotes: 3

Views: 460

Answers (1)

Daniel Fischer
Daniel Fischer

Reputation: 183878

If you have a monad transformer stack, each of the runXyzT functions of the individual transformers has to be called at some point, there is unfortunately no shortcut.

However, if you use a particular stack more than once, it is worthwhile to define a special runMyStack function, so that the clutter of the stacked runXyzT appears only at one point.

Upvotes: 6

Related Questions