
On Thu, Sep 20, 2007 at 03:23:05PM +0100, Jon Fairbairn wrote:
Henning Thielemann
writes: On Mon, 17 Sep 2007, Jon Fairbairn wrote:
instance Arrow (->) where ... (***) = (Data.Tuple.***) (&&&) = (Data.Tuple.&&&)
and modules that imported only Arrow (not Tuple) would see no difference from the present state of affairs. Where things would be different would be if a module imported both Tuple and Arrow, when, instead of a name clash, *** and &&& would get their Arrow meanings (albeit with a specialised instance for ->).
If you import Tuple and Arrow, why not just import Arrow?
Presumably because there are functions in Tuple that aren't in Arrow (if that isn't the case, this just means that Tuple/Arrow isn't a very good example).
Another example would be mplus. I happen to think that ++ is a good name for mplus, but unfortunately it's used up for append on lists -- which, curiously enough is mplus for lists. Examples of functions that are used at a specialised case and as class members abound, and I'd like to see a way round using lots of different names for the same concept. While one /can/ use different names, or manage the problem by using related names, to my mind use of a convention to tame the Babel of names indicates a deficiency in the language.
The reason ++ and mplus is so similar is that they used to be the same; (++) *was* the MonadPlus class member. Cale Gibbard explains this as {{{Quite a few people on the Haskell 98 committee had an irrational fear of polymorphism.}}} Stefan