
On Sun, Dec 29, 2013 at 07:06:26PM +0000, Tom Ellis wrote:
On Sun, Dec 29, 2013 at 06:50:15PM +0100, Hans Höglund wrote:
According to [1], Wrap/Compose does indeed have a Monad instance terms of traverse (here called 'swap'). As far as I understand the paper includes a proof that all the Monad laws holds for such as composition
[1]: http://web.cecs.pdx.edu/~mpj/pubs/RR-1004.pdf, page 9
Careful, they mention in Section 6.4 that "this construction only yields a composite monad if m has a certain commutativity property".
This is the same reason that 'ListT m' is not a monad unless 'm' is commutative.
What is your use case for these combinators? Perhaps you are using them exactly in a commutative case.
Having thought about your original question some more, I think the best approach would be to use a free monad like this import Control.Monad.Free data F m n a = L (m a) | R (n a) type Wrap m n = Free (F m n) so then 'Wrap m n' genuinely is a monad, and you can write a function condense :: (Monad m, Monad n, Traversable n, ...) => Wrap m n a -> m (n a) to collect up the results at the end. Then we need not bother to check whether anything satisfies any laws. 'condense' is similar to your original 'mjoin'. Tom (PS This is overkill for the current discussion, but: since you're starting with 'm' and 'n' monads anyway, using a free monad transformer (Control.Monad.Trans.Free) would probably reduce the boilerplate needed in 'condense'.)