Here's a minimal example out of my code demonstrating the problem:
module Substring = struct
type t = {
base: string;
pos: int;
len: int
}
end
module Parser = struct
type 'a t = Substring.t -> ('a * Substring.t) option
let return x s = Some (x, s)
end
type (_, _) t =
| TryParse : unit Parser.t -> ('a, 'a) t
| Parse : 'b Parser.t -> ('a, 'b -> 'a) t
| Concat : ('b, 'c) t * ('a, 'b) t -> ('a, 'c) t
let p = Parse (Parser.return "xxx")
My problem is that I want val p : ('a, string -> 'a) t
to be polymorphic and yet OCaml makes 'a
weak: val p : ('_a, string -> '_a)
. I'm pretty sure I'm being bitten by the value restriction here and I'm not quite sure how to get around it.
Yes, this is the value restriction. You need to eta-expand the problematic definition, like this:
let p = Parse (fun x -> Parser.return "xxx" x)
Annoying, isn't it?
If you want a binding to be polymorphic then you usually have to ensure that it is a "syntactic value". An expression containing a partial application doesn't qualify (because in general partial applications may have an effect), but a (fun ...)
is fine.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With