Cont as Monoid

Conor McBride ctm at cs.nott.ac.uk
Sun Sep 9 07:58:25 EDT 2007


Hi Conal

Conal:
 > I'd like to see the following addition to Control.Monad.Cont in mtl:
 >
 > instance Monoid r => Monoid (Cont r a) where
 >     mempty         = Cont mempty
 >     m `mappend` m' = Cont (runCont m `mappend` runCont m')

Does newtype deriving work here?

Stefan:
 > (My 2 cents: Why not mempty = return mempty; mappend = liftM2  
mappend ?
 > Instances are best if unambiguous.)

Conal:
 > I sure don't know how to resolve these situations of more than one  
credible
 > instance.  I'm seeing more & more of them.

My usual rule of thumb is that inherent natural monoidal structure  
should have
a higher priority than just applicative lifting of monoidal structure  
from the
value type. Here it's a bit harder to call because it's a choice of  
two lifts,
but I'd suggest that (Cont r) has natural monoidal structure if r is  
a monoid,
and hence this should take precedence over the applicative lifting  
(which is
what liftM2 does, but with too restrictive a type).

I guess my fairly feeble reason for this rule of thumb is that it  
fits with
what one would expect for []. It may also be to do with the way I  
read types:
when I see a type application (f t), I think of it as an f-like thing  
with
t-like details, hence the natural properties of f are somehow the more
significant. Moreover, preferring the f-specific thing is no big deal  
if you
have a cheap and uniform way to get the other thing (eg, liftA2 or idiom
brackets). The f-specific thing usually requires special  
consideration, hence
benefits most from overloading.

So I'm with you on this one.

All the best

Conor



More information about the Libraries mailing list