
Heinrich Apfelmus wrote:
Alternatively, you can use algebraic data types instead of type classes to generalize one program to different implementations. For monads, this can be achieved with
http://hackage.haskell.org/package/MonadPrompt
In particular, the idea is to turn every effect like
getLine
into a constructor
GetLine
and have different implementations pattern match on that.
Ooo, that's interesting... I did wonder for a moment whether this would allow you to analyse what the monadic action does without actually "doing" it, but on reflection this is fundamentally impossible. The action that happens next can (and often does) depend on the result of a previous effect. I guess if you wanted to run your action through an optimiser before actually running it, you'd need to use arrows (and all the terrifying syntax that entails)...