[Haskell-beginners] Fwd: Averaging a string of numbers

Brent Yorgey byorgey at seas.upenn.edu
Mon Dec 12 19:53:11 CET 2011


On Mon, Dec 12, 2011 at 10:00:35AM -0500, Dean Herington wrote:
> At 9:04 PM +1000 12/12/11, Ben Kolera wrote:
> >There is some magic here that I'm not quite groking. Sorry for my
> >slowness; but I seem to be missing a step:
> 
> Oops, my bad!  The magic is an inadequate test ;-).  Thanks for
> spotting the bug!
> 
> The magic I was trying to leverage is this instance from Data.Monoid:
> 
> instance Monoid a => Monoid (Maybe a) where
>   mempty = Nothing
>   Nothing `mappend` m = m
>   m `mappend` Nothing = m
>   Just m1 `mappend` Just m2 = Just (m1 `mappend` m2)

Just to provide a bit of perspective at this point: the reason this
Monoid instance for (Maybe a) can't be used is because it requires a
to be an instance of Monoid... but numbers under min/max DON'T form a
Monoid since there is no identity element.  In fact, that's the very
reason why we wanted to use Maybe in the first place!

I therefore consider this Monoid instance for Maybe "broken".  What we
really want is

  instance Semigroup a => Monoid (Maybe a) where ...

A semigroup is a set with an associative binary operation (but not
necessarily an identity element).  Maybe turns any semigroup into a
monoid by adding a "synthetic" identity element (namely, Nothing).  In
fact, such an instance is provided in the 'semigroups' package on
Hackage (except for a type called Option instead of Maybe).

Maybe someday we will get semigroups defined in 'base'.  That would be
nice.

-Brent



More information about the Beginners mailing list