caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
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

  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;
as well as URLs for NNTP newsgroup(s).