From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.1.3 (2006-06-01) on yquem.inria.fr X-Spam-Level: * X-Spam-Status: No, score=1.0 required=5.0 tests=AWL,SPF_FAIL autolearn=disabled version=3.1.3 X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from discorde.inria.fr (discorde.inria.fr [192.93.2.38]) by yquem.inria.fr (Postfix) with ESMTP id 5E1EEBC0C for ; Fri, 19 Jan 2007 12:22:20 +0100 (CET) Received: from mail.gmx.net (mail.gmx.net [213.165.64.20]) by discorde.inria.fr (8.13.6/8.13.6) with SMTP id l0JBMJOX009174 for ; Fri, 19 Jan 2007 12:22:20 +0100 Received: (qmail invoked by alias); 19 Jan 2007 11:22:18 -0000 Received: from dialin-145-254-250-081.pools.arcor-ip.net (EHLO dialin-145-254-250-081.pools.arcor-ip.net) [145.254.250.81] by mail.gmx.net (mp008) with SMTP; 19 Jan 2007 12:22:18 +0100 X-Authenticated: #11134691 Received: from dirk by feanor.private-host.de with local (masqmail 0.2.20) id 1H7rhV-1Fx-00 for ; Fri, 19 Jan 2007 12:14:29 +0100 Date: Fri, 19 Jan 2007 12:14:29 +0100 To: caml-list@yquem.inria.fr Subject: Re: Fwd: [Caml-list] Polymorphic Variants Message-ID: <20070119111429.GA4822@feanor> References: <200701182114.10133.jon@ffconsultancy.com> <20070119092648.GA3604@feanor> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.6+20040523i From: Dirk Thierbach X-Y-GMX-Trusted: 0 X-Miltered: at discorde with ID 45B0A9EB.000 by Joe's j-chkmail (http://j-chkmail . ensmp . fr)! X-Spam: no; 0.00; variants:01 0100,:01 overloading:01 haskell's:01 overloading:01 infix:01 forall:01 forall:01 bignum:01 matrices:01 bignum:01 compiler:01 haskell's:01 notation:01 compiler:01 [Please don't reply directly to me AND to the list, just to the list is enough. Thanks.] On Fri, Jan 19, 2007 at 11:35:36AM +0100, Tom wrote: > On 19/01/07, Dirk Thierbach wrote: > Well, in some sense, generic value overloading is somewhat like Haskell's > type classes, Yes. That's exactly what type classes are for -- overloading of functions (including infix operators). > 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 That's both longer and not extensible -- what if you're going to link a module the offers matrices? Don't you also want to use the function in that context? > or, what I would prefer: > > [int -> int | float -> float | complex -> complex | fraction -> > fraction | bignum -> bignum | int32 -> int32 | vector2 -> vector2 | vector3 > -> vector3 | string -> string] That's even worse :-) > (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. And that's exactly what the Haskell compiler does (see below). BTW, the important thing is the type variable after the predicate, just ignore the forall's for the moment. So the above type is nonsense, a possible example type could look like: (Num a, Floating b) => a -> a -> b -> b -> (a, b) And it's quite easy to read: The function itself has type a -> a -> b -> b -> (a, b) where all the a's represent the same type, and all the b's represent the same type, as usual in type inference. Moreover, every concrete type for "a" must be an instance of Num (i.e., float, complex, fraction, whatever, you don't care -- the important point is that it is "a number"), and "b" must be a instance of Floating (same idea). > >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? It can overload integer and fixed point literals (in the way described above). It cannot overload any other "values" (whatever that should be :-). And yes, it can overload functions by their return type: Num a => Integer -> a is a legal type (for example, it's the type of the function "fromInteger"). It really doesn't matter if the type variable "a" appears as argument or as the result (or, more generally, in a covariant or contravariant position). If you want more details, I'd recommend to have a look at the Haskell docs or tutorials. - Dirk