9

In the error monad, the first failure halts any execution further just carrying the fault through any following binds.

What monad halts on success only carrying forward successes, and basically swallowing any faults and trying the next bind disregarding the failure of the previous one?

The error monad could maybe be used for this treating failure like success, but I'm curious if the default libraries have a monad for this specific purpose, almost like an Or monad in my mind "Do this, or that"

Edit:

Behaviour would be:

Left "fail" >>= (\x -> Right "win") >>= (\x -> Left "ahh neener") >>= (\x -> Right (x + " yay"))

In the error monad the first left value is just carried forward, so the result of that is Left "fail". The behaviour I want is where the above returns Right "win yay" it's a trivial monad to implement I could write myself, but figured something existed to do such (maybe not using Either, but that's the first thing that comes to mind for such behaviour).

3
  • Why the downvote? Is there something bad about this question? Jan 20, 2013 at 5:33
  • Could you provide a small code snippet to show what your thinking? Jan 20, 2013 at 9:13
  • Could it be that you are thinking of backtracking?
    – scarfridge
    Jan 20, 2013 at 10:48

1 Answer 1

4

What you need is MonadPlus (see also Haskell wiki). It defines

mzero :: m a

which represents an unspecified error, and

mplus :: m a -> m a -> m a

which tries the second computation, if the first one fails. A few auxiliary functions are provided too:

-- Extends `mplus` to lists of computations:
msum :: MonadPlus m => [m a] -> m a
-- Fails a computation conditionally.
guard :: MonadPlus m => Bool -> m ()
-- Filter (fail) computations that don't satisfy the predicate.
mfilter :: MonadPlus m => (a -> Bool) -> m a -> m a

Instances of MonadPlus can be divided into two categories:

  1. mplus combines all possible results from both its arguments (satisfies Left Distribution law). [] and Seq are probably the only instances with this behavior.
  2. mplus selects the left argument, if it contains a valid value, otherwise it selects the right one (satisfies Left Catch law). Instances with this behavior are Maybe, Either, STM and IO.

(MonadPlus instance of Either used to be defined in Control.Monad.Error as

instance (Error e) => MonadPlus (Either e) where
    mzero            = Left noMsg
    Left _ `mplus` n = n
    m      `mplus` _ = m

but for some reason it seems to be missing in the current version.)

See also MonadPlus on Wikibooks and MonadPlus definition for Haskell IO.

4
  • Thanks, sounds like monadplus list is the thought I had. Jan 20, 2013 at 13:35
  • @JimmyHoffa I forgot to mention that Seq is also an instance of MonadPlus. I'd strongly recommend it over [], because concatenation (mplus) for Seq is O(log n) whereas concatenation of lists is O(n).
    – Petr
    Jan 20, 2013 at 13:46
  • The haskell wiki is very illuminating, sounds like the haskell community is pondering which way it should go in the same way I'm pondering which way I want it to work; whether I want it to be an Or as a "This or that" or a then, "This then that" where the first one failing causes behaviour like Or using the pre-failure value for the next one, but a success still calls the next one unlike Or and uses the value returned from the first function. Jan 22, 2013 at 17:34
  • Yes, I support the MonadPlus reform proposal, I believe this would clarify things a lot.
    – Petr
    Jan 22, 2013 at 18:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.