caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Dawid Toton <d0@wp.pl>
To: caml-list <caml-list@yquem.inria.fr>
Subject: [Caml-list] Re: References and polymorphism
Date: Wed, 11 Jan 2012 14:00:24 +0100	[thread overview]
Message-ID: <4F0D87E8.90602@wp.pl> (raw)
In-Reply-To: <CAPFanBGAyytgavTmooUChTkEQwLY-Fv9igduas55RN12EPcvPw@mail.gmail.com>

On 2012-01-11 12:07, Gabriel Scherer wrote:
> How would you make the distinction between
>
>    let f : 'a . unit ->  'a list ref =
>      fun () ->  ref ([] : 'a list)
>
> and
>
>    let f : 'a . unit ->  'a list ref =
>      let r = ref ([] : 'a list) in
>      fun () ->  r
>
> ?
>
I think that it's not the value restriction which prevents the second 
example from have generalized type.
Here's how I uderstand it.

First, we write the code, but don't put a quantifier in the annotation 
for f:

let f : unit ->  'a list ref =
   let r = ref ([] : 'a list) in
   fun () ->  r


Then, compiler tries to determine what does it mean. I think it should 
see it in the following way:

∃'b.
let f : X 'a. (unit -> 'a list ref) =
   let r = ref ([] : 'b list) in
   fun () -> r

where X stays for an unknown quantifier: generalize or not? We can try 
with forall:

∃'b.
let f : ∀ 'a. (unit -> 'a list ref) =
   let r = ref ([] : 'b list) in
   fun () -> r

But this doesn't typecheck: you cannot pass a value of type 'b list ref 
with some particular 'b and pretend that it works for some unrelated 'a.

A second possibility:
∃'b.
let f : ∃'a. (unit -> 'a list ref) =
   let r = ref ([] : 'b list) in
   fun () -> r

Here, nothing special happens. The compiler discovers that 'a='b. The 
toplevel translates this quantification to an underscore and we get unit 
-> '_a list ref.

I have considered several variations around this theme and no one needs 
the extra value restriction rule:

∀'a.(
let f : unit -> 'a list ref =
   let r = ref ([] : 'a list) in
   fun () -> r
)

(* above: Anonymous mapping from types to functions. Useless. *)

let f0 : ∀'a. (unit -> ∀'b. 'b list ref) =
   let r = ref ([] : ∀'c. 'c list) in
   fun (type 'aa) ->
     fun () ->
       r

(* f0: Sound, but returns useless ref [] constant. Its type ∀'b. 'b list 
ref could be forbidden. *)

let f1 : ∀'a . (unit -> 'a list ref) =
   let r = ref ([] : 'a list) in
   fun (type 'aa) ->
     fun () ->
       r

(* f1: Problem with type variable scope. The quantifier encompasses what 
is in brackets in the annotation for f1. Function body cannot refer to 
'a bound by this quantifier. It wouldn't make sense. *)

let f2 : ∀'a . (unit -> 'a list ref) =
   let r = ref ([] : ∀'c. 'c list) in
   fun (type 'aa) ->
     fun () ->
       r

(* f2: Type of function body (for each type return a constant/degenerate 
cell) is incompatible with the type given in the annotation (for each 
type return an useful ref cell). But it would be simpler just to avoid 
the useless type of r entirely. *)

let f3 : ∀'a . unit -> 'a list ref =
   fun (type 'aa) ->
     let r = ref ([] : 'aa list) in
     fun () ->
       r

(* f3: Fine, but it would require some work at compile time or smart 
transformations to keep types erased at run-time. Also, keeping the 
first actual argument (staying for 'aa) implicit would need extra rules 
to resolve ambiguities (decide when this argument is applied). *)

let f4 : ∀'a . unit -> 'a list ref =
   fun (type 'aa) ->
     fun () ->
       let r = ref ([] : 'aa list) in
       r

(* f4: All clear. *)

Dawid

  reply	other threads:[~2012-01-11 13:00 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-01-10 15:29 [Caml-list] " Dario Teixeira
2012-01-10 15:45 ` Romain Bardou
2012-01-10 16:31   ` Arnaud Spiwack
2012-01-10 17:00 ` Dario Teixeira
2012-01-10 17:20   ` David Allsopp
2012-01-10 18:59     ` Gabriel Scherer
2012-01-11 10:48     ` [Caml-list] " Dawid Toton
2012-01-11 11:07       ` Gabriel Scherer
2012-01-11 13:00         ` Dawid Toton [this message]
2012-01-11 13:15           ` rossberg
2012-01-11 13:56             ` Dawid Toton
2012-01-11 15:42               ` rossberg
2012-01-12  9:55                 ` Dawid Toton
2012-01-12 10:05                   ` Andrej Bauer
2012-01-12 10:46                     ` Romain Bardou
2012-01-11 11:43       ` rossberg
2012-01-11 13:34         ` Dawid Toton
2012-01-11 15:34           ` rossberg
2012-01-11 13:57         ` Dawid Toton

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=4F0D87E8.90602@wp.pl \
    --to=d0@wp.pl \
    --cc=caml-list@yquem.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).