
On 12/03/2013, at 3:15 AM, Carlos Camarao wrote:
On Sat, Mar 9, 2013 at 5:33 PM, Peter Caspers
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.