On 19/01/07, Dirk Thierbach <dthierbach@gmx.de> wrote:
On Thu, Jan 18, 2007 at 09:14:09PM +0000, Jon Harrop wrote:
> On Thursday 18 January 2007 16:23, Tom wrote:
>> No... i rather thought it that way:
>> x is anything
>> x * x is either int or float, so x is either int or float
>> x * x + x * x is either int or float, so the two (x * x) are either
>> both int or both float
>> sqrt accepts a float argument, so x * x + x * x must be float, so (x *
>> x) must be float, so x must be float.
BTW, that's what Haskell's type classes do:
Well, in some sense, generic value overloading is somewhat like
Haskell's type classes, with an advantage that type classes are infered
automatically by the compiler (or, actually, are not named/declared -
the compiler simply lists all types belonging to the current typeclass
Prelude> :t \x -> x
\x -> x :: forall t. t -> t
Prelude> :t \x -> x * x
\x -> x * x :: forall a. (Num a) => a -> a
forall a . (int, float, complex, fraction, bignum, int32, vector2, vector3, string) => a -> a
or, what I would prefer:
[int -> int | float -> float | complex -> complex | fraction -> fraction | bignum -> bignum | int32 -> int32 | vector2 -> vector2 | vector3 -> vector3 | string -> string]
(Yes, it seems a lot of writing... but remember that it is not you who writes that, it's the compiler. While for such short types, a -> a, Haskell's notation is better, it could become hard to understand with more complex types:
forall a . (float, complex, fraction) => forall b . (int, string) => a -> a -> b -> b -> (a, b)
Now, go figure all the possibilities... It's much simpler when the compiler lists all the combinations for you.
> Hell, I want to overload 0 to mean 0, 0., 0. + 0.i, zero vector and
> the zero matrix.
No problem either: Number literals like "0" are translated into the
expression "fromInteger 0", so by overloading fromInteger in the
type class, you can generate the apropriate constant.
Can Haskell overload values? And functions by their return type?