Compiler errors OCaml变量类型泛化

Compiler errors OCaml变量类型泛化,compiler-errors,compilation,polymorphism,ocaml,Compiler Errors,Compilation,Polymorphism,Ocaml,我正在尝试使用ocamlc编译以下代码 type 'a splitter = {name: string; decision_function : 'a -> bool} let splitter12a = {name="x1>x2"; decision_function=(fun x -> x.(1)>x.(2))};; let generate_splitter i j = {name="x"^string_of_int(i)^">x"^string_o

我正在尝试使用ocamlc编译以下代码

type 'a splitter = {name: string; decision_function : 'a  -> bool}

let splitter12a = {name="x1>x2"; decision_function=(fun x -> x.(1)>x.(2))};;

let generate_splitter i j  = {name="x"^string_of_int(i)^">x"^string_of_int(j); decision_function=(fun x -> x.(i) > x.(j))} ;; 

let splitter12 = generate_splitter 1 2;;
但是,编译器抱怨:

File "error.ml", line 7, characters 17-38:
Error: The type of this expression, '_a array splitter,
       contains type variables that cannot be generalized

我不明白为什么我可以声明一个专用的
拆分器12a
,而
生成拆分器
不能生成专用拆分器。

您遇到了所谓的值限制。有关说明,请参见《真实世界Ocaml手册》中相同标题的章节


编辑:通常的解决方法(可能在该章中建议)是eta扩展,意思是扩展出一个λ,例如,通过将定义
let f=ga
转换为
let f x=ga x
。但这不适用于您的情况,因为def的RHS不会产生函数。对于您想要做的事情,确实没有直接的解决方法

一种方法是将其转化为函子:

module MakeSplitter (X : sig val i : int val j : int end) =
struct
  let splitter = {name = "x"^string_of_int(i)^">x"^string_of_int(j); decision_function = fun x -> x.(i) > x.(j)}
end

module Splitter12 = MakeSplitter(struct val i = 1 val j = 2 end)
let splitter12 = Splitter12.splitter

另一种方法是使用带有多态字段的辅助记录类型,非常类似于上面的结构。

谢谢!什么是最体面的解决办法?我不熟悉“eta扩展”,专门化拆分器(我现在使用的解决方案)不是一个可行的解决方案确实没有直接的解决方案,但请参见我的编辑。