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=0.0 required=5.0 tests=AWL autolearn=disabled version=3.1.3 X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) by yquem.inria.fr (Postfix) with ESMTP id 08092BBAF for ; Wed, 11 Mar 2009 04:16:44 +0100 (CET) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: As0CANDJtknYi40JmWdsb2JhbACBTpNgAQEBAQEICwoHEbxChA0G X-IronPort-AV: E=Sophos;i="4.38,339,1233529200"; d="scan'208";a="22357896" Received: from unknown (HELO mail.nyct.net) ([216.139.141.9]) by mail2-smtp-roc.national.inria.fr with ESMTP; 11 Mar 2009 04:16:43 +0100 Received: from beast.local (pool-96-250-33-211.nycmny.east.verizon.net [96.250.33.211]) (authenticated bits=0) by mail.nyct.net (8.14.2/8.14.1) with ESMTP id n2B3Gbm7007109 (version=TLSv1/SSLv3 cipher=DHE-DSS-AES256-SHA bits=256 verify=NO); Tue, 10 Mar 2009 23:16:39 -0400 (EDT) (envelope-from bhurt@spnz.org) Date: Tue, 10 Mar 2009 23:16:19 -0400 (EDT) From: Brian Hurt X-X-Sender: bhurt@beast To: Jon Harrop Cc: caml-list@yquem.inria.fr Subject: Re: [Caml-list] stl? In-Reply-To: <200903042303.07629.jon@ffconsultancy.com> Message-ID: References: <91a2ba3e0903031340wcdc976cp52522eb35f7ccb73@mail.gmail.com> <87ab81yrog.fsf@aryx.cs.uiuc.edu> <200903042303.07629.jon@ffconsultancy.com> User-Agent: Alpine 2.00 (DEB 1167 2008-08-23) MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed X-Spam: no; 0.00; stl:01 functors:01 ocaml:01 comming:01 struct:01 sig:01 val:01 val:01 bool:01 bool:01 iter:01 functor:01 mismatch:01 sig:01 iter:01 Sorry for the late reply- I was out of town over the weekend. On Wed, 4 Mar 2009, Jon Harrop wrote: > On Wednesday 04 March 2009 21:59:51 Brian Hurt wrote: >> But seriously, you hate functors that much? The overhead of doing: >> >> module StringMap = Map.Make(String);; >> >> is so high to you, that you simply don't do it? >> >> Mind if I ask why? > > Your example is fragile: it doesn't work with Int and Float because they were > never written: > > $ ocaml > Objective Caml version 3.09.1 > > # module IntMap = Map.Make(Int);; > Unbound module Int > # module FloatMap = Map.Make(Float);; > Unbound module Float This isn't a limitation of the language, this is simply a short comming of the standard libraries. > > So you have to define a temporary module by hand in general: > > # module IntMap = Map.Make(struct type t = int let compare = compare end);; > module IntMap : > sig > type key = int > type +'a t > val empty : 'a t > val is_empty : 'a t -> bool > val add : key -> 'a -> 'a t -> 'a t > val find : key -> 'a t -> 'a > val remove : key -> 'a t -> 'a t > val mem : key -> 'a t -> bool > val iter : (key -> 'a -> unit) -> 'a t -> unit > val map : ('a -> 'b) -> 'a t -> 'b t > val mapi : (key -> 'a -> 'b) -> 'a t -> 'b t > val fold : (key -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b > val compare : ('a -> 'a -> int) -> 'a t -> 'a t -> int > val equal : ('a -> 'a -> bool) -> 'a t -> 'a t -> bool > end > > You want a mapping to IntMaps but IntMap is parameterised and the Map.Make > functor cannot handle that: > > # module IntMapMap = Map.Make(IntMap);; > Signature mismatch: > Modules do not match: > sig > type key = int > type 'a t = 'a IntMap.t > val empty : 'a t > val is_empty : 'a t -> bool > val add : key -> 'a -> 'a t -> 'a t > val find : key -> 'a t -> 'a > val remove : key -> 'a t -> 'a t > val mem : key -> 'a t -> bool > val iter : (key -> 'a -> unit) -> 'a t -> unit > val map : ('a -> 'b) -> 'a t -> 'b t > val mapi : (key -> 'a -> 'b) -> 'a t -> 'b t > val fold : (key -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b > val compare : ('a -> 'a -> int) -> 'a t -> 'a t -> int > val equal : ('a -> 'a -> bool) -> 'a t -> 'a t -> bool > end > is not included in > Map.OrderedType > Type declarations do not match: > type 'a t = 'a IntMap.t > is not included in > type t How do you know how to compare two generic types? Yes, you need another functor here, to give a comparison function for the types being held. Note that the functors propogate in exactly the same way as type class dependencies propogate. Here is one place where (small) changes to the language, the addition of some syntactic sugar, could make things a lot more usefull. I'm thinking of something like making => a special operator, so that: Ord t => let foo (x: t) (y : t) = ... is the same as: module Foo(X: Ord) = struct type t = X.t;; open X;; let foo (x: t) (y: t) = ... end;; or something. And some similar bit of syntactic sugar to make instantiating a functor lower cost as well. Obviously this idea has some problems. My point is that is that it should be possible to come up with some sort of reasonable extension of the language to allow functors to be more "type-class like". Brian