[Haskell-cafe] Overloading

Richard A. O'Keefe ok at cs.otago.ac.nz
Mon Mar 11 21:44:32 CET 2013


On 12/03/2013, at 3:15 AM, Carlos Camarao wrote:

> On Sat, Mar 9, 2013 at 5:33 PM, Peter Caspers <pcaspers1973 at gmail.com> wrote:
> 
>     Hi,
> 
>     I just started playing around a bit with Haskell, so sorry in
>     advance for very basic (and maybe stupid) questions. Coming from
>     the C++ world one thing I would like to do is overloading
>     operators. For example I want to write (Date 6 6 1973) + (Period 2
>     Months) for some self defined types Date and Period. Another
>     example would be (Period 1 Years) + (Period 3 Months).
> 
>     Just defining the operator (+) does not work because it collides
>     with Prelude.+. I assume using fully qualified names would work,
>     but that is not what I want.
> 
> 
> Hi. To define (+) as an overloaded operator in Haskell, you have to define
> and use a type class.

Stop right there.  Overloading in the C++ sense is "ad hoc polymorphism"
where the signatures of the various definitions need not resemble each
other in any way.  Haskell just plain does not have anything like that.
(+) in Haskell is *not* overloaded; it has several implementations and
allows you to define as many more as you want.  But they all conform to
the *SAME* interface.  This is much more like OO inheritance.

In particular, C++ will let you define versions of + where the arguments
are of two different types and the result is a third.  You cannot provide
such an implementation for Haskell's predefined (+).
> 
> Furthermore, Haskell supports a more powerful form of overloading than
> (any other language I know, including) C++: context-dependent
> overloading. This means that the type of an expression (f e), and thus
> of f, can be determined at compile-time (inferred) based on the
> context where (f e) occurs, not only on the type of the
> argument (e) of the function's call.

Ada has had this since Ada 81.  The design goal that forced it was
the wish to allow the same identifier to be used as an enumeral in
more than one enumerated type, so that you could do

   type Colour is (Red, Green, Blue);
   type Fruit_State is (Green, Ripe, Rotten);
   X : Colour := Green;
   Y : Fruit_State := Green;

and in particular, since character literals like 'X' are allowed as
enumerals in Ada, they wished to be able to write

    A: EBCDIC_Character := 'X';
    B: ASCII_Character  := 'X';

and have A and B be different bytes.  The difference is that Ada
*does* do this sort of thing using overload resolution and Haskell
*doesn't*.

> 
> For example, you _could_ in principle use (d+p==d) and (d+p==p), 
> with d::Date, p::Period, and instances of (+) with types 
> Date->Period->Date and Date->Period->Period, if you wish…

Prelude> :type (+)
(+) :: Num a => a -> a -> a

The predefined (+) in Haskell requires its arguments and its result
to be precisely the same type.

I think you had better justify the claim that Date+Period -> Date and
Date+Period -> Period are possible at the same time by showing us
actual code.




More information about the Haskell-Cafe mailing list