[Haskell-cafe] Inverting a Monad
Bas van Dijk
v.dijk.bas at gmail.com
Wed Feb 6 06:32:40 EST 2008
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
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
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.
More information about the Haskell-Cafe