
I wrote:
...the main monad at work here is the Exit monad.
Ross Paterson wrote:
...if we define exitMaybe :: Exit e () -> Maybe e exitMaybe (Continue _) = Nothing exitMaybe (Exit e) = Just e then we have runExit m = fromJust (exitMaybe m) exitMaybe (x >> y) = exitMaybe x `mplus` exitMaybe y exitMaybe (maybeExit m) = m so we can replace the Exit monad with Maybe.
Maybe monads quit on failure and continue on success. We want the opposite semantics for guards, pattern matching, and the like. The Exit monad is the dual of the Maybe monad in this sense. In particular, your identity
exitMaybe (x >> y) = exitMaybe x `mplus` exitMaybe y
is not true. If we let x = Continue () and y = Exit z, then exitMaybe (x >> y) = Just z but exitMaybe x `mplus` exitMaybe y = Nothing -Yitz