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 mail3-relais-sop.national.inria.fr (mail3-relais-sop.national.inria.fr [192.134.164.104]) by sympa.inria.fr (Postfix) with ESMTPS id 2ACE57F02D for ; Tue, 21 Oct 2014 14:47:55 +0200 (CEST) Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of lpw25@cam.ac.uk) identity=pra; client-ip=131.111.8.152; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="lpw25@cam.ac.uk"; x-sender="lpw25@cam.ac.uk"; x-conformance=sidf_compatible Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of lpw25@cam.ac.uk) identity=mailfrom; client-ip=131.111.8.152; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="lpw25@cam.ac.uk"; x-sender="lpw25@cam.ac.uk"; x-conformance=sidf_compatible Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of postmaster@ppsw-52.csi.cam.ac.uk) identity=helo; client-ip=131.111.8.152; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="lpw25@cam.ac.uk"; x-sender="postmaster@ppsw-52.csi.cam.ac.uk"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AhsEAMRIRlSDbwiYnGdsb2JhbABcvUkGmlQCgQ4WAREBAQEBAQgLCQkULoQDAQEDASdSBQsLISUPAQRJLogcCAS9QYVXAQEBBwEBAQEeGIYLii4HhEsFnwqQcYd5gzYBAQE X-IPAS-Result: AhsEAMRIRlSDbwiYnGdsb2JhbABcvUkGmlQCgQ4WAREBAQEBAQgLCQkULoQDAQEDASdSBQsLISUPAQRJLogcCAS9QYVXAQEBBwEBAQEeGIYLii4HhEsFnwqQcYd5gzYBAQE X-IronPort-AV: E=Sophos;i="5.04,762,1406584800"; d="scan'208";a="84088012" Received: from ppsw-52.csi.cam.ac.uk ([131.111.8.152]) by mail3-smtp-sop.national.inria.fr with ESMTP/TLS/DHE-RSA-AES256-SHA; 21 Oct 2014 14:47:54 +0200 X-Cam-AntiVirus: no malware found X-Cam-ScannerInfo: http://www.cam.ac.uk/cs/email/scanner/ Received: from host86-181-34-203.range86-181.btcentralplus.com ([86.181.34.203]:38965 helo=netbook) by ppsw-52.csi.cam.ac.uk (smtp.hermes.cam.ac.uk [131.111.8.159]:587) with esmtpsa (PLAIN:lpw25) (TLSv1.2:AES128-GCM-SHA256:128) id 1XgYqw-0006Cq-D7 (Exim 4.82_3-c0e5623) (return-path ); Tue, 21 Oct 2014 13:47:54 +0100 From: Leo White To: Arnaud Spiwack Cc: OCaML Mailing List References: <8638ahpq1m.fsf@cam.ac.uk> X-Face: "XWxb[u_Z\PA_Y?9@|IA!!+jTb(/290-*ea/Un$I0B98.$n%eL.;2w*,z]WR#T:,p[ NBd++M7l]#7zj7!{~iw $W-"/=|dVjhT[D{4~gE}gK<2`.6fs!;uqqud]vs2N/3^m7{aS1V, Date: Tue, 21 Oct 2014 13:47:53 +0100 In-Reply-To: <8638ahpq1m.fsf@cam.ac.uk> (Leo White's message of "Tue, 21 Oct 2014 13:26:13 +0100") Message-ID: <86y4s9oah2.fsf@cam.ac.uk> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain Subject: Re: [Caml-list] Manipulating Modules Modularly > Moving quantifiers around is awkward in the module system, but is also > not safe in general. We can clearly illustrate this by reencoding your > example without modules: > > First we define `m` as a record type and create one for lists: > > # type 'a m = { u : 'a; p : 'a -> 'a -> 'a };; > type 'a m = { u : 'a; p : 'a -> 'a -> 'a; } > > # let list = { u = []; p = (@) };; > val list : 'a list m = {u = []; p = } > > Then we define the `me` as another record type and create a simple > function for creating them from monoids: > > # type 'a me = { ps : 'a list -> 'a };; > type 'a me = { ps : 'a list -> 'a; } > > # let me (m : 'a m) = { ps = List.fold_left m.p m.u };; > val me : 'a m -> 'a me = > > Now we can apply the `me` function to the `list` monoid: > > # let mel = me list;; > val mel : '_a list me = {ps = } > > But what we get is only weakly polymophic because of the value > restriction. It is worth noting we can eta-expand to avoid the value restriction: # type 'a me = 'a list -> 'a;; type 'a me = 'a list -> 'a # let me (m : 'a m) : 'a me = List.fold_left m.p m.u;; val me : 'a m -> 'a me = # let mel : 'a list me = fun l -> me list l;; val mel : 'a list me = Which is just equivalent to the solution you already described: >> With local modules it is reasonably easy to implement LE without modifying ME, by re-exporting every function as a >> function which instantiates LEF (though I guess [u] would only work because list is covariant). But I would rather the >> module LE to extend automatically as I extend the signature of ME. However, since we are using the core language instead of the module language, we get type inference and can avoid repeating ourselves so much. Perhaps this is an acceptable solution for your use cases. Regards, Leo