On Tue, Mar 12, 2013 at 5:54 PM, Richard A. O'Keefe <ok@cs.otago.ac.nz> 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