以下是我的代码演示问题的最小示例:
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")
我的问题是,我希望val p : ('a, string -> 'a) t
具有多态性,但OCaml使'a
变弱:val p : ('_a, string -> '_a)
。我很确定我被这里的价值限制所困扰,而且我不太确定如何绕过它。
答案 0 :(得分:5)
是的,这是价值限制。您需要eta扩展有问题的定义,如下所示:
let p = Parse (fun x -> Parser.return "xxx" x)
烦人,不是吗?
如果您希望绑定具有多态性,那么您通常必须确保它是一个“语法值”。包含部分应用程序的表达式不符合条件(因为通常部分应用程序可能会产生影响),但(fun ...)
没问题。