From: Reed Wilson <cedilla@gmail.com>
To: Caml List <caml-list@inria.fr>
Cc: Leo White <leo@lpw25.net>,
mandrykin@ispras.ru, Jeremy Yallop <yallop@gmail.com>
Subject: Re: [Caml-list] Type generalization confusion
Date: Wed, 10 May 2017 11:14:11 -0700 [thread overview]
Message-ID: <CALLFq5TXUaHnr6zeSGdogh6_c9ECFgtqyd51pgGfxBth8oM33Q@mail.gmail.com> (raw)
In-Reply-To: <CAAxsn=EgzfTjHWF_xM7KnggEoA0kfT9MV+ttw9NwQ8R4LJTwHg@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 2856 bytes --]
On Tue, May 9, 2017 at 1:54 PM, Jeremy Yallop <yallop@gmail.com> wrote:
> On 9 May 2017 at 20:56, Reed Wilson <cedilla@gmail.com> wrote:
> > The current issue I'm actually facing is trying to create a lookup table
> for
> > these templates, which only differ by the length of some of the fields.
> For
> > example:
> >
> > let lookup_array = [| String (0, End); String (1, End) |]
>
> The value restriction prevents generalization here, since arrays are
> mutable. If bindings of array expressions were generalized then the
> following program, which writes to the array at one type (int option)
> and reads from the array at a different type (string option), would be
> allowed.
>
> let array = [| None |] in (* val array : 'a option
> array *)
> let () = array.(0) <- Some 3 in
> let Some x = array.(0) in (* val x : 'a *)
> "abc" ^ x
>
> So it's essential for soundness that the types of array values are not
> generalized.
>
I suppose I should have known why the array didn't work, I just didn't
realize it since nothing I have defines a type that would have made that
unsoundness cause problems.
On Wed, May 10, 2017 at 6:29 AM, Mikhail Mandrykin <mandrykin@ispras.ru>
wrote:
> type (_, _) field =
> | Int8 : ('a, 'b) field -> ((int -> 'a),'b) field
> | String : int * ('a, 'b) field -> ((string -> 'a), 'b) field
> | End : ('b, 'b) field
> type 'a lookup_param = { f : 'b. ('a -> 'b, 'b) field } [@@unboxed]
> let lookup_array = [| { f = String (0, End) }; { f = String (1, End) } |]
> let lookup i = match lookup_array.(i) with { f } -> f
> let of_chan : ('a, 'b) field -> 'a -> in_channel -> 'b = fun _ _ _ ->
> assert
> false
> let x = of_chan (lookup 0) (fun s -> int_of_string s) stdin
> let y = of_chan (lookup 0) (fun s -> s) stdin
>
This is an interesting work-around. I had to tweak it a bit since it would
only work with templates that have one "field". For example:
let lookup_array = [| {f = Int8 (String (0, End))} |]
fails with:
Error: This expression has type (int -> string -> 'a, 'a) field
but an expression was expected of type
(int -> string -> 'a, string -> 'a) field
The type variable 'a occurs inside string -> 'a
Luckily, that's not a problem in my case since I only need this for one
field type, so I changed it to be a bit less general:
type lookup_param = { f : 'b. (int -> string -> 'b, 'b) field }
And everything works fine. This will let me test the speed difference
between an extra pointer lookup vs. allocating ~15 words per loop for my
actual code. Honestly, my guess is that this is all academic since OCaml is
so good at small allocations, but I really wanted to know why things
weren't working.
Thanks again to everyone who responded!
--
ç
[-- Attachment #2: Type: text/html, Size: 4812 bytes --]
next prev parent reply other threads:[~2017-05-10 18:14 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-05-08 18:32 Reed Wilson
2017-05-09 3:49 ` Gabriel Scherer
2017-05-09 5:43 ` Reed Wilson
2017-05-09 8:54 ` Leo White
2017-05-09 19:56 ` Reed Wilson
2017-05-09 20:54 ` Jeremy Yallop
2017-05-10 18:14 ` Reed Wilson [this message]
2017-05-10 13:29 ` 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=CALLFq5TXUaHnr6zeSGdogh6_c9ECFgtqyd51pgGfxBth8oM33Q@mail.gmail.com \
--to=cedilla@gmail.com \
--cc=caml-list@inria.fr \
--cc=leo@lpw25.net \
--cc=mandrykin@ispras.ru \
--cc=yallop@gmail.com \
/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