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 mail1-relais-roc.national.inria.fr (mail1-relais-roc.national.inria.fr [192.134.164.82]) by yquem.inria.fr (Postfix) with ESMTP id 87D3ABBAF for ; Fri, 27 Jun 2008 22:09:21 +0200 (CEST) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AoMAAF/lZEjUGyodmmdsb2JhbACBW5EKAQEBAQEIBQgHEQOZbYVA X-IronPort-AV: E=Sophos;i="4.27,716,1204498800"; d="scan'208";a="14511465" Received: from smtp3-g19.free.fr ([212.27.42.29]) by mail1-smtp-roc.national.inria.fr with ESMTP; 27 Jun 2008 22:09:21 +0200 Received: from smtp3-g19.free.fr (localhost.localdomain [127.0.0.1]) by smtp3-g19.free.fr (Postfix) with ESMTP id 0A16D17B52D for ; Fri, 27 Jun 2008 22:09:21 +0200 (CEST) Received: from localhost.localdomain (c5850-a2-3-62-147-9-24.dial.proxad.net [62.147.9.24]) by smtp3-g19.free.fr (Postfix) with ESMTP id B618417B54C for ; Fri, 27 Jun 2008 22:09:19 +0200 (CEST) Date: Fri, 27 Jun 2008 20:10:01 +0200 From: Fabrice Marchant To: caml-list@yquem.inria.fr Subject: Re: [Caml-list] Building a Set module for elements of a Map Message-ID: <20080627201001.7cc5d751@free.fr> In-Reply-To: <20080625153043.3bd7895c@free.fr> References: <20080625153043.3bd7895c@free.fr> X-Mailer: Claws Mail 3.2.0 (GTK+ 2.12.10; i486-pc-linux-gnu) X-Face: Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable X-Spam: no; 0.00; filliatre:01 pervasives:01 pervasives:01 functor:01 orderedtype:01 struct:01 orderedtype:01 struct:01 printf:01 printf:01 elt:01 'with:98 wrote:01 parameterize:01 caml-list:01 Thanks for the useful and interesting answers ! Jean-Christophe Filli=E2tre explained: > Using Pervasives.compare instead of a user-defined comparison function > may even be incorrect. (Suppose the intended comparison function should > identify (x,y) and (y,x), for instance; obviously, Pervasives.compare > will not.) Your clearly exposed things with this example. I suspected my trial was n= ot perfect. I now understand it is erroneous. > A possible solution to your problem is to have functor F taking instead > a module for keys as argument, and then to build module M inside F; thus > it would look like: > > module F(K : OrderedType) =3D struct > module M =3D Map.Make(K) > module MKeySet =3D Set.Make(K) > ... > end =20 I wanted to extend the functionalities of the Map module. Your solution per= fectly suits what I need : module MapPlus(K : Map.OrderedType) =3D struct module M =3D Map.Make(K) include M module MKeySet =3D Set.Make(K) let of_list l =3D List.fold_left (fun a (x, y) -> M.add x y a) M.empty l let domain map =3D M.fold (fun k _ -> MKeySet.add k) map MKeySet.empty end module StringMap =3D MapPlus.MapPlus( String ) let sm =3D StringMap.of_list ["one", 1; "two", 2; "three", 3] let print l =3D Printf.printf "{%s}" (String.concat ", " l) let _ =3D print (StringMap.MKeySet.elements (StringMap.domain sm)) (* -> {one, three, two} *) Xavier Leroy wrote : > Yet another alternative is to parameterize F over both a Map and a Set, > adding a sharing constraint to ensure that they work on compatible > data types: > >module F (M: Map.S) (MKeySet: Set.S with type elt =3D M.key) =3D struct > ... >end I discover ! Never have thought we could use 'with type elt' constraint thi= s way. ---------------------------------------------------------------- So you cleanly solved the problem to get the domain set of a map. Please how would you build the module MValSet to express the range set of a= map ? ( Inside MapPlus module, by : let range map =3D M.fold (fun _ v -> MValSet.add v) map MValSet.empty ) Regards, Fabrice