[Haskell-cafe] Inverting a Monad

Bas van Dijk v.dijk.bas at gmail.com
Wed Feb 6 06:32:40 EST 2008


Hello,

Is there a way to 'invert' an arbitrary Monad?

By 'inverting' I mean to turn success into failure and failure into
success. Here are some specific inversions of the Maybe and List
Monad:

invM :: Maybe a -> Maybe ()
invM Nothing  = Just ()
invM (Just _) = Nothing

invL :: [] a -> [] ()
invL []    = [()]
invL (_:_) = []


How can I define this for an arbitrary Monad m?

More specifically, I would like to define:

inv :: (Monad m, M.MonadPlus m, ???) => m a -> m ()
inv m = if m fails    then return ()
        if m succeeds then fail

The following obviously doesn't work:

inv m = (m >> mzero) `mplus` return ()

because it will always return ().


There's also a 'inversion' for natural numbers:

invN :: Int -> Int
invN 0 = 1
invN n = 0

but how can I define that without pattern matching, so only using
arithmetic operations, +, -, *, ^, ...?


The reason I ask this is that I'm writing a parser combinator library
to understand parser a bit better. And I would like to define the
combinator:

notFollowedBy :: P t m a -> P t m ()

'notFollowedBy p' fails when p succeeds and returns () when p fails.

I will share the code when it's a bit more polished.


Thanks,

Bas


More information about the Haskell-Cafe mailing list