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