From: Jacques Garrigue <garrigue@math.nagoya-u.ac.jp>
To: Dmitry Grebeniuk <gdsfh1@gmail.com>
Cc: caml-list@inria.fr
Subject: Re: [Caml-list] value restriction and records' rank-2 polymorphism
Date: Tue, 21 Jun 2011 17:31:57 +0900 [thread overview]
Message-ID: <A298E6EA-54DE-45EA-900B-740258C18E61@math.nagoya-u.ac.jp> (raw)
In-Reply-To: <BANLkTi=jqHn_u3nWXM4t_K2T30Byh55AXA@mail.gmail.com>
On 2011/06/21, at 16:13, Dmitry Grebeniuk wrote:
> Hello.
>
> I need to create two functions that share common state, and I want to
> create this common state once per program run, and I want to make each
> function call very cheap. When I'm doing it naively, I get "value restriction":
>
> $ ocaml
> # #use "topfind";;
> # #camlp4r;;
> # type func 'a 'r = string -> ('a -> 'r) -> 'r;
> type func 'a 'b = string -> ('a -> 'b) -> 'b
> # value identity x = x;
> value identity : 'a -> 'a = <fun>
[...]
> But I've found a trick that uses rank-2 polymorphism of record fields:
>
> # type pair 'a 'b =
> { notnull : !'r . func 'a 'r
> ; nullable : !'r . func (option 'a) 'r
> };
> type pair 'a 'b =
> { notnull : !'c. func 'a 'c; nullable : !'d. func (option 'a) 'd }
> # value mkpair2 from_string =
> (* some common values here *)
> { notnull = fun s f -> try f (from_string s) with [e -> failwith "mkpair2"]
> ; nullable = fun s f -> try f (Some (from_string s)) with [e -> f None]
> };
> value mkpair2 : (string -> 'a) -> pair 'a 'b = <fun>
> # value { notnull = id21 ; nullable = id22 } = mkpair2 identity;
> value id21 : func string 'a = <fun>
> value id22 : func (option string) 'a = <fun>
> #
>
> And everything seems to work: the record is created once, then
> it is "decomposed" to id21 and id22 functions (either right after its
> creation or on each call, it should be cheap anyway). But I don't
> know whether this solution is correct and will it remain correct in
> future versions of OCaml -- can you help me here?
I'm not sure I understand the details of all you are trying do,
but there is no plan to remove polymorphic record fields from the
language, so you can use this feature safely.
(Strictly speaking, this is a language extension, so there may be
some changes in the future, but there is nothing planned)
Since 3.12, an alternative approach which should be just as cheap
is to use a first class module. This is a bit more verbose.
module type Pair = sig
type t
val notnull : (t,'r) func
val nullable : (t option, 'r) func
end
let mkpair (type a) from_string =
(module struct
type t = a
let notnull s f = try f (from_string s) with e -> failwith "mkpair"
let nullable s f = try f (Some (from_string s)) with e -> f None
end : Pair with type t = a)
module M = (val (mkpair (fun x -> x)) : Pair with type t = string)
let id31 = M.notnull
let id32 = M.nullable
Jacques Garrigue
next prev parent reply other threads:[~2011-06-21 8:32 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-06-21 7:13 Dmitry Grebeniuk
2011-06-21 8:31 ` Jacques Garrigue [this message]
2011-06-21 8:55 ` Dmitry Grebeniuk
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=A298E6EA-54DE-45EA-900B-740258C18E61@math.nagoya-u.ac.jp \
--to=garrigue@math.nagoya-u.ac.jp \
--cc=caml-list@inria.fr \
--cc=gdsfh1@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