On Dec 17, 2011, at 12:51 PM, Matthew Farkas-Dyck wrote:

> By my reason, the instance (Monoid a => Monoid (Maybe a)) is
> appropriate, since we have another class for inner-type-agnostic
> choice -- Alternative! (and MonadPlus, but that's essentially the
> same, and would be if (Functor m => Applicative m => Monad m), as it
> ought).

Yes, but the problem here is that having different behavior for Alternative, 
MonadPlus, and Monoid instances is inherently confusing, in the sense that this 
would almost certainly surprise someone who wasn't already aware of the 
difference between the instances.

Regardless, even if we keep the current behavior, we *really* *really* need to 
improve the documentation for the Monoid instance of Maybe.  Currently it reads:

 "Lift a semigroup into Maybe forming a Monoid according to 
http://en.wikipedia.org/wiki/Monoid: "Any semigroup S may be turned into a 
monoid simply by adjoining an element e not in S and defining e*e = eand e*s = 
s = s*e for all s  S." Since there is no "Semigroup" typeclass providing just 
mappend, we use Monoid instead."

Now, I just happened to have recently spent time studying the properties of 
Semigroups and Monoids, so this explanation made perfect sense to me and was a 
beautiful way of explaining what is going on.  A typical user, however --- 
which would have included me roughly one month ago :-) --- would have looked at 
this and just seen goobledegook which reinforced their perception that Haskell 
is first and foremost a playground for mathematicians.  It would be much, much 
better for the documentation to be something like this:

============================================================

The Monoid instance for Maybe has the property that, for all x and y, (Just x) 
wins when combined (on either side) with Nothing values, and when (Just x) is 
combined with (Just y) then the result is (Just (x `mappend` y)).

For the more mathematically inclined, you may think of this as being equivalent 
to the standard practice of turning an arbitrary semigroup into a monoid by 
simply adding a new element to the semigroup to serve as the identity element, 
where in this case the identity element is the Nothing value of Maybe;  
unfortunately, since the base libraries do not come with a Semigroup typeclass, 
this process is expressed in code as lifting from the Monoid typeclass.

NOTE THAT the behavior of the Monoid instance of Maybe is DIFFERENT from the 
behavior of the MonadPlus and Alternative instance of Maybe.  For the latter 
two typeclasses, the behavior is that when (Just x) is combined with (Just y) 
the x and y values themselves are not combined but rather y is discarded so 
(Just x) simply wins;  put another way, for all x and z, we have that (Just x) 
`mappend` z is *always* equal to (Just x), regardless of whether z is equal to 
Nothing or whether it is equal to (Just y) for some y.  For this reason, unlike 
the instance for Monoid, the instances for these MonadPlus and Alternative 
place no additional constraints on the type lifted into Maybe.

============================================================

Incidentally, would people be interested in me sending a patch to update the 
documentation to be more along these lines?  (After applying your feedback, of 
course!)  If so, could you point me to where I could learn about the process 
for doing so?

Cheers,
Greg
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to