[Haskell-cafe] Swapping Monads
dominic.steinitz at blueyonder.co.uk
Tue Jul 8 01:39:13 EDT 2008
I have a solution so this is for interest only.
It is not normally the case that two monads compose to give another
monad. Monad transformers capture when this is possible. However, when
there is a "swap" function satisfying some commutative diagrams then it
can be proved that the monads compose to produce a monad.
Is there such a swap function in a library? I had a look in the
comprehensive category-extra package but couldn't find anything.
Here's two possible implementations. Big caveat: I haven't proved that
these satisfy the commutative diagrams but I am confident that they will.
Option 1 define
swap :: (Functor m, Monad m) => Either String (m a) -> m (Either String a)
swap (Left s) = return (Left s)
swap (Right x) = fmap Right x
Option 2 use Traversable (EvilTerran's suggestion)
instance F.Foldable (Either String) where
foldMap f (Left s) = mempty
foldMap f (Right x) = f x
instance T.Traversable (Either String) where
traverse f (Left s) = pure (Left s)
traverse f (Right x) = Right <$> f x
and now you can use T.sequence to swap the monads around.
For further information see Composing Monads by Mark Jones and Luc
Duponcheel and Toposes, Triples and Theories by Barr & Wells (Section 9.2).
More information about the Haskell-Cafe