caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Markus Mottl <markus.mottl@gmail.com>
To: Jacques Garrigue <garrigue@math.nagoya-u.ac.jp>
Cc: OCaml List <caml-list@yquem.inria.fr>
Subject: Re: [Caml-list] Late adding of type variable constraints
Date: Fri, 4 Sep 2015 19:58:26 -0400	[thread overview]
Message-ID: <CAP_800pqmi692PfOEx7++JOM6hA9rVHc-YD8MWD8yGJpjyvPWg@mail.gmail.com> (raw)
In-Reply-To: <B4CA33D4-108C-4308-9A4B-4D336DAF5811@math.nagoya-u.ac.jp>

I see.  So it's not really a matter of soundness, but the type checker
changes would presumably be overly intrusive and possibly cause issues
with efficiency.  Ultimately, I wanted to be able to constrain type
variables via a functor argument, which is also apparently not
possible.

Maybe there are alternative solutions to what I'm trying to do, which
is actually a quite neat type system challenge:

Imagine you have a datastructure that is parameterized over an unknown
number of type variables.  Given such a datastructure, I want to be
able to map all these type variables from one type to another while
preserving the "skeleton" of that structure, but without limiting the
skeleton constructors to a specific number of type variables.

Lets assume the "skeleton" is the option type.  The first part of the
(slightly simplified) solution compiles just fine:

---
module type S = sig
  type 'a t
  type ('a, 'b) mapper

  val map : ('a, 'b) mapper -> 'a t -> 'b t
end

module Option (Arg : S) = struct
  type 'a t = 'a Arg.t option
  type ('a, 'b) mapper = ('a, 'b) Arg.mapper

  let map mapper = function
    | None -> None
    | Some el -> Some (Arg.map mapper el)
end
---

In order to introduce any number of type variables, I thought one
could use the following neat trick (example with two variables):

---
module Arg1 = struct
  type 'args t = 'arg1 constraint 'args = 'arg1 * _

  type ('src, 'dst) mapper = {
    map1 : 'src1 -> 'dst1;
    map2 : 'src2 -> 'dst2;
  }
  constraint 'src = 'src1 * 'src2
  constraint 'dst = 'dst1 * 'dst2

  let map mapper arg1 = mapper.map1 arg1
end
---

But "Option (Arg1)" will not type-check, because the constraints are
missing in signature "S".  This is unfortunate, because I think the
code would be correct.  The body of "Option" should preserve any
constraint on the type variables.

Is there any alternative that preserves extensibility, i.e. an
implementation of "Option" that will work with any number of type
parameters?

On Fri, Sep 4, 2015 at 6:19 PM, Jacques Garrigue
<garrigue@math.nagoya-u.ac.jp> wrote:
> On 2015/09/04 13:28, Markus Mottl <markus.mottl@gmail.com> wrote:
>>
>> Hi,
>>
>> I wonder whether there is a way to add constraints to type variables
>> in signatures after the signature was defined.  E.g.:
>>
>> ---
>> module type S = sig
>>  type 'a t
>>  type ('a, 'b) mappers
>>
>>  val map : ('a, 'b) mappers -> 'a t -> 'b t
>> end
>>
>> module type T = sig
>>  type 'a t constraint 'a = unit  (* whatever *)
>>  include S with type 'a t := 'a t
>> end
>> ---
>>
>> The above will fail, because 'a has additional constraints for type
>> "t" in signature "T".  If I write instead e.g. "type 'a t = 'a list",
>> this will work and also constrain the signature to something narrower.
>> What makes constraints on polymorphic variables special here?
>
> Consider this signature:
>
> module type S = sig
>   type 'a t
>   type 'a u = U of 'a t constraint 'a = < m: int; .. >
> end
>
> Now the signature
>    S with type 'a constraint 'a t = unit
> is ill-typed, but to see it you must type-check again all of its contents
> (not just the definition of t).
>
> This is the reason you cannot do that.
>
> Jacques Garrigue



-- 
Markus Mottl        http://www.ocaml.info        markus.mottl@gmail.com

  reply	other threads:[~2015-09-04 23:58 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-09-04 20:28 Markus Mottl
2015-09-04 22:19 ` Jacques Garrigue
2015-09-04 23:58   ` Markus Mottl [this message]
2015-09-07 18:33     ` Mikhail Mandrykin
2015-09-09 14:00       ` Markus Mottl
2015-09-09 19:28         ` Mikhail Mandrykin
2015-09-11 15:56           ` Markus Mottl
2015-09-11 16:24             ` Mikhail Mandrykin

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=CAP_800pqmi692PfOEx7++JOM6hA9rVHc-YD8MWD8yGJpjyvPWg@mail.gmail.com \
    --to=markus.mottl@gmail.com \
    --cc=caml-list@yquem.inria.fr \
    --cc=garrigue@math.nagoya-u.ac.jp \
    /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).