* [Caml-list] value restriction and records' rank-2 polymorphism
@ 2011-06-21 7:13 Dmitry Grebeniuk
2011-06-21 8:31 ` Jacques Garrigue
0 siblings, 1 reply; 3+ messages in thread
From: Dmitry Grebeniuk @ 2011-06-21 7:13 UTC (permalink / raw)
To: caml-list
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 mkpair1 from_string =
(* some common values here *)
( fun s f -> try f (from_string s) with [e -> failwith "mkpair1"]
, fun s f -> try f (Some (from_string s)) with [e -> f None]
);
value mkpair1 :
('a -> 'b) -> ('a -> ('b -> 'c) -> 'c * 'a -> (option 'b -> 'd) -> 'd) = <fun>
# value identity x = x;
value identity : 'a -> 'a = <fun>
# value (id11, id12) = mkpair1 identity;
value id11 : '_a -> ('_a -> '_b) -> '_b = <fun>
value id12 : '_a -> (option '_a -> '_b) -> '_b = <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?
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [Caml-list] value restriction and records' rank-2 polymorphism
2011-06-21 7:13 [Caml-list] value restriction and records' rank-2 polymorphism Dmitry Grebeniuk
@ 2011-06-21 8:31 ` Jacques Garrigue
2011-06-21 8:55 ` Dmitry Grebeniuk
0 siblings, 1 reply; 3+ messages in thread
From: Jacques Garrigue @ 2011-06-21 8:31 UTC (permalink / raw)
To: Dmitry Grebeniuk; +Cc: caml-list
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
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2011-06-21 9:03 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-06-21 7:13 [Caml-list] value restriction and records' rank-2 polymorphism Dmitry Grebeniuk
2011-06-21 8:31 ` Jacques Garrigue
2011-06-21 8:55 ` Dmitry Grebeniuk
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox