From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail3-relais-sop.national.inria.fr (mail3-relais-sop.national.inria.fr [192.134.164.104]) by sympa.inria.fr (Postfix) with ESMTPS id D465E7FC86 for ; Fri, 20 Mar 2015 17:32:36 +0100 (CET) Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of dra-news@metastack.com) identity=pra; client-ip=62.13.149.58; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="dra-news@metastack.com"; x-sender="dra-news@metastack.com"; x-conformance=sidf_compatible Received-SPF: Pass (mail3-smtp-sop.national.inria.fr: domain of dra-news@metastack.com designates 62.13.149.58 as permitted sender) identity=mailfrom; client-ip=62.13.149.58; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="dra-news@metastack.com"; x-sender="dra-news@metastack.com"; x-conformance=sidf_compatible; x-record-type="v=spf1" Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of postmaster@outmail149058.authsmtp.co.uk) identity=helo; client-ip=62.13.149.58; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="dra-news@metastack.com"; x-sender="postmaster@outmail149058.authsmtp.co.uk"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A0BvAADfSgxVnDqVDT5cg1haszsGkxeHK0wBAQEBAQERAQEBAQEICwkJFC6EGwMFAh0BEkwFFlIjHAEEHgULiBgJogOqGhwEhgqOMgWQTGGDDZongXMBghxvAYJCAQEB X-IPAS-Result: A0BvAADfSgxVnDqVDT5cg1haszsGkxeHK0wBAQEBAQERAQEBAQEICwkJFC6EGwMFAh0BEkwFFlIjHAEEHgULiBgJogOqGhwEhgqOMgWQTGGDDZongXMBghxvAYJCAQEB X-IronPort-AV: E=Sophos;i="5.11,437,1422918000"; d="scan'208";a="104156628" Received: from outmail149058.authsmtp.co.uk ([62.13.149.58]) by mail3-smtp-sop.national.inria.fr with ESMTP; 20 Mar 2015 17:32:36 +0100 Received: from mail-c235.authsmtp.com (mail-c235.authsmtp.com [62.13.128.235]) by punt16.authsmtp.com (8.14.2/8.14.2/) with ESMTP id t2KGWZaM011930 for ; Fri, 20 Mar 2015 16:32:35 GMT Received: from romulus.metastack.com (cpc1-cmbg5-0-0-cust241.5-4.cable.virginm.net [81.98.252.242]) (authenticated bits=0) by mail.authsmtp.com (8.14.2/8.14.2/) with ESMTP id t2KGWXUN007987 for ; Fri, 20 Mar 2015 16:32:33 GMT Received: from Altus ([172.16.0.18]) (authenticated bits=0) by romulus.metastack.com (8.14.2/8.14.2) with ESMTP id t2KGWW0Y012536 (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NO) for ; Fri, 20 Mar 2015 16:32:33 GMT From: "David Allsopp" To: "OCaml List" Date: Fri, 20 Mar 2015 16:29:45 -0000 Organization: MetaStack Solutions Ltd. Message-ID: <002a01d0632b$13cb79b0$3b626d10$@metastack.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-Mailer: Microsoft Outlook 14.0 Thread-Index: AdBjKcmF5udA17O5Rfqrjp3aYUwbdA== Content-Language: en-gb X-Scanned-By: MIMEDefang 2.65 on 172.16.0.20 X-Server-Quench: b60191ce-cf1e-11e4-b396-002590a15da7 X-AuthReport-Spam: If SPAM / abuse - report it at: http://www.authsmtp.com/abuse X-AuthRoute: OCd1ZAARAlZZVg1f DC4bFwdFRBksPQFF ChxFJgxfNlEAUAAU NkdBMnJSNkcdTBdX QSgJW0spAR9uW2N0 bhpQaw9eYEBNXEti UVZASkxQEQd2AxgD GRwbTRk8Mwc9DxkY ADhiXndSVEM0dkJ9 RQAGE20HbGYzPX1M BkENagJVJQdXLBxM bE1/VHEIaGVWZ380 FlAlGjcrMH1SOCVO XgwLMVMbRQ4GBTU1 Xx0ZVXUoBwUdQD4o LhYiOxYSHVwKLg05 NVI6QhoANBsDDwpE B0FMGyoYTwAA X-Authentic-SMTP: 61633634383431.1023:706 X-AuthFastPath: 0 (Was 255) X-AuthSMTP-Origin: 81.98.252.242/25 X-AuthVirus-Status: No virus detected - but ensure you scan with your own anti-virus system. Subject: [Caml-list] More existential escapes (or possibly first class polymorphism) Daniel's recent thread inspired to revisit a recent problem I'd had but had given up on, with a most inelegant solution. Although what I have no is much less inelegant, I'm wondering if it can be improved further by a trick or some such which I can't spot. I have a GADT containing keys where the type parameter denotes the value type (my actual use case has many more constructors): type _ token = Block : int -> string token | Role : string -> unit token and I then want to be able to store these in a structure where I can look them up by token value. So I define: type binding = B : ('a token * 'a) -> token to store a binding and: type (_, _) eq = Eq : ('a, 'a) eq let test_key (type r) (type s) (r : r token) (s : s token) : (r, s) eq option = match (r, s) with (Role r, Role s) when r = s -> Some Eq | (Block r, Block s) when r = s -> Some Eq | _ -> None and so I can define [find] in a manner very like Daniel's in https://sympa.inria.fr/sympa/arc/caml-list/2015-03/msg00109.html Given that this application is for a specific set of keys, rather than for a universal type, I'd quite like to define [iter], which is where I've hit a bit of inelegance: let iter f script = let rec iter = function binding::script -> f binding; iter script | [] -> () in iter script but this means that the function passed needs to match on type binding, which I'd prefer to be hidden: let f = function B(Role role, ()) -> Printf.printf "Role %s\n%!" role | B(Block n, code) -> Printf.printf "Block %d\n%!" n code Is there a way to write [iter] such that it has signature [('a token -> 'a -> unit) -> binding list -> unit]? My closest attempt so far is to start with: let iter f script = let rec iter = function B(key, binding)::script -> f key binding; iter script | [] -> () in iter script which obviously doesn't work because the type of [key] and [binding] in [iter] escape their scope. Now, if my understanding is correct, the problem here isn't so much that the existentials escape their scope, but that [f] is monomorphic. So, if I define a record type: type f = {f : 'a . 'a token -> 'a -> unit} then I can alter the definition of iter to allow a polymorphic function to be passed let iter {f} script = ... and I can get to a version of [iter] where the functions don't need to know about the internals of type binding, but they do need to be passed wrapped up as {f: foo}. Is there some other wizardry on offer which can allow the polymorphic nature of [f] to be inferred? David