From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@sympa.inria.fr Delivered-To: caml-list@sympa.inria.fr Received: from mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) by sympa.inria.fr (Postfix) with ESMTPS id AB7927EE25 for ; Thu, 14 Nov 2013 13:11:39 +0100 (CET) Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of dhouse@janestreet.com) identity=pra; client-ip=38.105.200.229; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="dhouse@janestreet.com"; x-sender="dhouse@janestreet.com"; x-conformance=sidf_compatible Received-SPF: Pass (mail2-smtp-roc.national.inria.fr: domain of dhouse@janestreet.com designates 38.105.200.229 as permitted sender) identity=mailfrom; client-ip=38.105.200.229; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="dhouse@janestreet.com"; x-sender="dhouse@janestreet.com"; x-conformance=sidf_compatible; x-record-type="v=spf1" Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of postmaster@tot-dmz-mxout1.janestreet.com) identity=helo; client-ip=38.105.200.229; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="dhouse@janestreet.com"; x-sender="postmaster@tot-dmz-mxout1.janestreet.com"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AmEBAPO8hFImacjlnGdsb2JhbABagz9HDKxKklaBGR4OAQEBAQEGDQkJFCiCJQEBBUABASwLAQ8LCwMKDSEiEgEFAQoSBhMSh10DDwMCCKEciw6EUgEFhR4DiW8GjywzB4QxmBOBL45xGCmEUw X-IPAS-Result: AmEBAPO8hFImacjlnGdsb2JhbABagz9HDKxKklaBGR4OAQEBAQEGDQkJFCiCJQEBBUABASwLAQ8LCwMKDSEiEgEFAQoSBhMSh10DDwMCCKEciw6EUgEFhR4DiW8GjywzB4QxmBOBL45xGCmEUw X-IronPort-AV: E=Sophos;i="4.93,699,1378850400"; d="scan'208";a="42733511" Received: from mx5.janestreet.com (HELO tot-dmz-mxout1.janestreet.com) ([38.105.200.229]) by mail2-smtp-roc.national.inria.fr with ESMTP/TLS/DHE-RSA-AES256-SHA; 14 Nov 2013 13:11:38 +0100 Received: from tot-oib-smtp1.delacy.com ([172.27.22.15] helo=tot-smtp) by tot-dmz-mxout1.janestreet.com with esmtp (Exim 4.76) (envelope-from ) id 1Vgvlp-0007dR-MY for caml-list@inria.fr; Thu, 14 Nov 2013 07:11:37 -0500 Received: from tot-dmz-mxgoog1.delacy.com ([172.27.224.14] helo=mxgoog2.janestreet.com) by tot-smtp with esmtps (TLSv1:AES256-SHA:256) (Exim 4.72) (envelope-from ) id 1Vgvlp-0002R3-LW for caml-list@inria.fr; Thu, 14 Nov 2013 07:11:37 -0500 Received: from mail-qc0-f172.google.com ([209.85.216.172]) by mxgoog2.janestreet.com with esmtp (Exim 4.76) (envelope-from ) id 1Vgvlp-00073G-Gr for caml-list@inria.fr; Thu, 14 Nov 2013 07:11:37 -0500 Received: by mail-qc0-f172.google.com with SMTP id q4so881906qcx.31 for ; Thu, 14 Nov 2013 04:11:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=janestreet.com; s=google; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type:content-transfer-encoding; bh=RLePkbBL3ulcxKKu+UsjiDDCXVENLzg0rc0C+vM0POI=; b=ffovsNsdq7gMz/ZnMLa7kAuDYpBErJcZ3qOyhPmcfHlCbRAE9igmptBnhzJbzatTqB MUHBrjGSFi6+beKYktxVivEpvm6Lkoel9brvoLmA3yGxWbMJSJHr8EINTV65mg4WlXwU D43FcIu0o6DpyGScEFHOUL60lQO7WS5nis1Hw= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type :content-transfer-encoding; bh=RLePkbBL3ulcxKKu+UsjiDDCXVENLzg0rc0C+vM0POI=; b=QXhN20RPztwKZYR+FttLnpw7gKYq7I0m02awxbsi6gSjIbQi6ChCrB202PRn4HMbU3 96g4DbQ0QpXWkIKC39PvcKPwRXCMl9OqN+qZ5bK+w/E1uxG/YdBEQvix5Gz/aezXzWbe Wdt6I2XZKnhTRl0lxhCi9wrVtMnRX3AMti49fBODYrJAhsjLfPAUjUFvyxZ3XtXBB11H r5mWfJe1ypSc4wtLIswSEbwr+OvgYF51BvyPBwYIzGtec0bBwcpxVCnVxi6SqB3FwjBF SXHNk2iINH+2aGkoWG1w/Oo8H4z+S8WiMpYYZFkiopCHXe9xhhoz+ErPWZWxDVqG4Vm/ 2E+w== X-Gm-Message-State: ALoCoQnsi1Buxt0j9feeEAi5AdV9s0r7Sc8UFCmmjbOFfqvB9YGxj6OenTdCUkNUN6IBu20O1nEhc+vdpC7N7BEF48tlV3mE2ZA2dqi0hPwcMAemH+Lvxx3pGjvCeyd1GKoPOrapq6TQhZliAMX0wzYzoU0MbgeoIw== X-Received: by 10.49.99.98 with SMTP id ep2mr1616995qeb.9.1384431097368; Thu, 14 Nov 2013 04:11:37 -0800 (PST) MIME-Version: 1.0 X-Received: by 10.49.99.98 with SMTP id ep2mr1616978qeb.9.1384431097248; Thu, 14 Nov 2013 04:11:37 -0800 (PST) Received: by 10.140.82.104 with HTTP; Thu, 14 Nov 2013 04:11:37 -0800 (PST) In-Reply-To: References: <7389AC6E-C25D-43B3-9A39-E59F92EF35AB@my.bristol.ac.uk> Date: Thu, 14 Nov 2013 12:11:37 +0000 Message-ID: From: David House To: Yaron Minsky Cc: Mark Shinwell , Ollie Frolovs , caml users Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Subject: Re: [Caml-list] Creating a Map from custom type To follow up on Mark's example, you can use the following slightly more general idiom: module My_thing =3D struct module T =3D struct type t =3D int * string * string with sexp, compare end include T include Comparable.Make(T) let do_some_stuff t =3D ... end Then My_thing will satisfy the Comparable signature, which means you'll have My_thing.Map, as well as My_thing.Set, My_thing.equal, My_thing.(<) etc. We do this on basically every type in core, since you'll want to use everything in a set sooner or later :) The "gold standard" for such types is the Identifiable signature. This is basically the union of the Comparable signature, the Hashable signature (which gives you hashtables, hash-sets etc.) and the Stringable signature (to/from strings). You can get there with just a little more work: module My_thing =3D struct module T =3D struct type t =3D ... with sexp, compare, bin_io let hash =3D Hashtbl.hash let to_string t =3D ... let of_string t =3D ... let module_name =3D "My_lib.My_thing" (* for the toplevel *) end include T include Identifiable.Make(T) (* other functions here *) end If you want the string representation to be the same as the sexp representation, that's possible too with only a little more clunkiness: module My_thing =3D struct module T =3D struct module T' =3D struct type t =3D ... with sexp, compare, bin_io end include T' include Sexpable.To_stringable(T') let hash =3D Hashtbl.hash let module_name =3D "My_lib.My_thing" (* for the toplevel *) end include T include Identifiable.Make(T) (* other functions here *) end On 14 November 2013 12:03, Yaron Minsky wrote: > It's worth noting that if you want a simply polymorphic map, you can > have one, you just need to be explicit about what you're doing: > > utop # let map =3D Map.Poly.of_alist_exn [1, "one"; 2, "two"; 3, "three"]= ;; > val map : (int, string) Map.Poly.t =3D > > which is probably the lowest-pain approach. Polymorphic compare > (which is what this is based on) has some downside, but is perfectly > good for many use-cases. RWO covers in detail the pitfalls of > polymorphic compare, but it doesn't mean you should avoid it, > especially when you're getting started. > > As for David's point about Core vs the stdlib, I think creating a map > with a polymorphic comparison function is actually quite a bit easier > in Core than it is with the stdlib, since no functor application is > required. > > y > > On Thu, Nov 14, 2013 at 6:21 AM, Mark Shinwell = wrote: >> On 14 November 2013 10:39, Ollie Frolovs wrot= e: >>> My current implementation uses associative lists, in subroute.ml: >>> >>> open Core.Std >>> type t =3D ((int list * int) * (int * int list)) list >>> let empty =3D [] >>> let to_list x =3D x >>> let add t k v =3D List.Assoc.add t k v >>> let find t k =3D List.Assoc.find t k >>> >>> I would like to use a Map instead. The key for my Map must have the typ= e (int list * int) and the values have the type (int * int list). If i unde= rstood it correctly, because the key is a tuple and not one of the built-in= simple data types (string, int, etc), because of this i have to provide a = custom comparator. This is first thing that i am not sure of. >> >> I think you need something like: >> >> module Key =3D struct >> type t =3D int list * int with sexp, compare >> end >> >> module My_map =3D Map.Make (Key) >> >> Then, for example: >> >> let map =3D >> My_map.add My_map.empty >> ~key:([42], 0) >> ~data:(1, [2]) >> >> The "with compare" auto-generates a "compare" function for >> you. Using explicit comparison functions, as Core strongly >> encourages, does unfortunately mean a bit more code at times >> but is arguably vastly more sustainable as your codebase >> grows. In such scenarios it becomes increasingly unlikely >> that the correct notion of comparison on one of your many >> abstract types coincides with the structural comparison >> on whatever implementation those types happen to have today. >> >> Mark >> >> -- >> Caml-list mailing list. Subscription management and archives: >> https://sympa.inria.fr/sympa/arc/caml-list >> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners >> Bug reports: http://caml.inria.fr/bin/caml-bugs > > -- > Caml-list mailing list. Subscription management and archives: > https://sympa.inria.fr/sympa/arc/caml-list > Beginner's list: http://groups.yahoo.com/group/ocaml_beginners > Bug reports: http://caml.inria.fr/bin/caml-bugs