
On Fri, Feb 10, 2006 at 05:20:47PM +0100, Niklas Broberg wrote:
class Monad m => MonadWriter m where type Output m tell :: Output m -> m ()
instance MonadWriter (MyWriterM w) where type Output m = [w] tell x = MyWriterM ((), [x])
This works fine, but the obvious question is then, where to put back the Monoid restriction? This time we want the type Output m to be constrained, so my naive first guess was to write:
perhaps
class Monad m => MonadWriter m where type Output m tell :: Monoid (Output m) => Output m -> m ()
? At least, this would let you do the same things, but is not quite equivalent. The main reason I can think of for the constraint is so that you can use the methods of said class in the default methods of a class. Including them like this would let you do that. however, this would mean dictionaries get passed to each method rather than being included in the MonadWriter dictionary so it is not quite equivalent. the Monoid constraint is actually important, so you can do things like:
-- double the pleasure, double the fun. newtype DWriter m a = DWriter m a
instance MonadWriter m => MonadWriter (DWriter m) where tell x = DWriter $ tell (x `mappend` x)
which would not work without the Monoid constraint on 'tell' or again, some sort of syntax to constrain the assosiated type on an instance declaration. So, perhaps we need this? I don't think the syntax you proposed
instance (MonadWriter m, Monoid (Output m)) => MonadWriter (DWriter m) where tell x = DWriter $ tell (x `mappend` x)
would be problematic, but am not sure... John -- John Meacham - ⑆repetae.net⑆john⑈