On Mon, Oct 23, 2006 at 11:27:58AM +0100, Conor McBride wrote:
> John Meacham wrote:
> >Although, now that we lost the Monoid instance for functions (which is
> >very dismaying), it is less useful, as the monoid functions were very
> >useful to build things up efficiently with (String -> String) as a type.
>> ...(with which I rather disagree) to finish a note about programming
> with structure-indicating newtypes, like Endo.
>> I thought I'd also remind you of a little of what we bought by wrapping
> the endofunction monoid, then making the function instance do pointwise
> lifting instead.
I don't have an issue with the reasoning behind it. But the transition
caused a lot of real and very subtle bugs that could have been avoided.
the problem is that there are many places where the change caused silent
changes to the behavior of existing code and these bugs were very hard
to root out.
for instance 6.4:
mconcat [('a':),('b':),('c':),('d':)] [] => "abcd"
and 6.6:
mconcat [('a':),('b':),('c':),('d':)] [] => "abcd"
but change it slightly:
6.4:
mconcat [('a':),('b':),('c':),('d':)] "foo" => "abcdfoo"
6.6:
mconcat [('a':),('b':),('c':),('d':)] "foo" => "afoobfoocfoodfoo"
a very subtle change when buried deep in your typechecking code, can
manifest in very strange and perplexing ways.
you can't even search for every use of 'mconcat' to find them, as a lot
of my uses were hidden inside of execWriter, or many other functions
that internally use monoids.
If someone on IRC didn't have the good idea of creating a dummy
conflicting instance, I would probably have been finding such bugs for
months to come...
also, all the data constructors created by Data.Monoid are nice, but
they are very common words and conflict with many pre-existing data
types, which is bad for something as commonly imported as Data.Monoid.
It would have been nicer to include them in somehing like
Data.Monoid.Strategies.
So, my beef wasn't so much with the reasoning behind the changes, but
the execution of them.
John
--
John Meacham - ⑆repetae.net⑆john⑈