
On Tue, Mar 12, 2013 at 5:54 PM, Richard A. O'Keefe
wrote: Carlos Camarao wrote:
>> Sorry, I think my sentence: >> "To define (+) as an overloaded operator in Haskell, >> you have to define and use a type class." >>is not quite correct. I meant that to define any operator in Haskell you have to >> have a type class defined with that operator as member.
> No. Operators and type classes are entirely orthogonal in Haskell. > For example, the list concatenation operator (++) is not defined in > any type class. It could be. Either the `mplus` of > MonadPlus or the `mappend` of Monoid would make sense. But it > happens not to be.
I have already corrected myself (repeating, I meant: "To define an _overloaded_ name or operator in Haskell you have to have a type class defined with that name/operator as member").
>> Yes, but the requirement of using the "predefined" (+) is an extra >> requirement (I would call (+) in Haskell not a predefined operator, >> but an operator whose type is defined in a class (Num) which is in the >> Prelude). A Haskell programmer can still define versions of (+) where >> the arguments are of two different types and the result is a third >> (he cannot though use the two type classes, and thus neither instances >> of these two type classes, in a program).
> I wish we could argue over semantics instead of vocabulary. > By calling the (+) of Num "predefined" I meant nothing other than > "it is _defined_ in the Haskell report before (_pre_) you or I add > any code of our own". We agree on the facts.
Ok. But the fact that (+) has type a->a->a is a matter (design decision) related to the definition of class Num in the Haskell Prelude. If (+) had type a->b->c, the fact that
"A Haskell programmer can still define versions of (+) where the arguments are of two different types and the result is a third"
would _not_ depend on hiding and redefining a type class. The programmer could then just define the desired instances.
> I don't call it an "extra" requirement. The original context > was very clearly that in C++ where you have int+int, int+double, > double+int, double+double, char*+int, int+char* and so on all > predefined, you can *also* add your own date+period *without* > hiding the predefined versions. And _that_ is overloading. > If the question is whether Haskell can do overloading, _that_ is > what has to be achieved: you can add a *new* interface > date+period *without* hiding the ones that were already defined > before you started coding.
See above. In this view redefining the type of (+) in class Num
as a->b->c would be sufficient for Haskell to have overloading.
> The interesting challenge here is that we should have > Date + Period -> Date Date - Period -> Date > Period + Date -> Date Period - Date -> ILLEGAL > Period + Period -> Deriod Period - Period -> Period > Date + Date -> ILLEGAL Date - Date -> Date > and _also_ (remember we are trying to beat C++ here) Int +/- Int -> Int. > > I suspect that this can be done using type-level programming (so that > Date + Date and Period - Date _begin_ to type check but then violate > a type constraint) but that's where my Haskell skills are most risible.
Without redefining the type of (+) in the Prelude, the challenge can be met by redefining (+) in another type class (and, yes, if Prelude.(+) is also needed, hiding and importing it qualified). Note though that in this case _polymorphic_ uses of (+), whose instantiation could be for instances of both classes (Prelude.Num and the other one) are not possible. Kind regards, Carlos