caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Leo White <lpw25@cam.ac.uk>
To: Arnaud Spiwack <arnaud@spiwack.net>
Cc: OCaML Mailing List <caml-list@inria.fr>
Subject: Re: [Caml-list] Manipulating Modules Modularly
Date: Tue, 21 Oct 2014 13:47:53 +0100	[thread overview]
Message-ID: <86y4s9oah2.fsf@cam.ac.uk> (raw)
In-Reply-To: <8638ahpq1m.fsf@cam.ac.uk> (Leo White's message of "Tue, 21 Oct 2014 13:26:13 +0100")

> 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 = <fun>}
>
> 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 = <fun>
>
> Now we can apply the `me` function to the `list` monoid:
>
>     # let mel = me list;;
>     val mel : '_a list me = {ps = <fun>}
>
> 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 = <fun>

    # let mel : 'a list me = fun l -> me list l;;
    val mel : 'a list me = <fun>

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

  reply	other threads:[~2014-10-21 12:47 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-10-21  8:52 Arnaud Spiwack
2014-10-21 12:26 ` Leo White
2014-10-21 12:47   ` Leo White [this message]
2014-10-21 13:19     ` Arnaud Spiwack
2014-10-21 14:52       ` Leo White
2014-10-22  9:51         ` Arnaud Spiwack

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=86y4s9oah2.fsf@cam.ac.uk \
    --to=lpw25@cam.ac.uk \
    --cc=arnaud@spiwack.net \
    --cc=caml-list@inria.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).