有没有一种方法可以在类型上参数化模块或从 OCaml 中的模块中转义类型?
Is there a way to parametrize a module on a type or escape a type from a module in OCaml?
有没有办法在 OCaml 中对类型的模块进行参数化或从模块中转义类型?基本上,我想编写一些在浮点类型上进行参数化的例程,并且仍然可以访问 (+.)、(-.) 等运算符。当然,我们可以编写一个浮点模块,如
module type REAL = sig
type t
val real : float->t
val (+.) : t->t->t
val (-.) : t->t->t
val ( *. ) : t->t->t
val (/.) : t->t->t
end
它对普通浮点数有一个非常基本的实现
module MyReal : REAL = struct
type t=float
let real x=x
let (+.) x y = x+.y
let (-.) x y = x-.y
let ( *. ) x y = x*.y
let (/.) x y = x/.y
end
然后,我尝试在代码为
的模块中本地使用这个模块
let double (type real) (module Real:REAL with type t = real) x =
let open Real in
x+.x
这个函数有我想要的类型
val double : (module REAL with type t = 'a) -> 'a -> 'a = <fun>
但是,如果我运行它,编译器会报错
# double (module MyReal) 1.0;;
Error: This expression has type float but an expression was expected of type
MyReal.t
当然,我们可以使用模块中的注入功能
# double (module MyReal) (MyReal.real 1.0);;
- : MyReal.t = <abstr>
但是结果类型是抽象的而不是浮点数。最终,我想要一种使函数 double return 成为公开类型的方法。如果可能的话,我不想在 REAL 模块中使用另一个函数来转换 t->float
。我希望以某种方式公开实际类型 t
。另外,我想要一种通过在本地使用模块而不是在 REAL
.
上参数化的仿函数来执行此操作的方法
您给 MyReal
的类型约束过于严格:MyReal : REAL
。它的类型 t
的实现被约束隐藏了。在使用 MyReal
、double (module MyReal) 1.0
时,类型 t
和 float
的统一失败,因为您隐藏了事实 t = float
.
修复如下:
module MyReal : REAL with type t = float = struct
...
end
但最好的方法是让 OCaml 自己推断 MyReal
的最一般类型:
module MyReal = struct
...
end
在这里,MyReal
和 REAL
的关系不太清楚,但 OCaml 的模块类型足够聪明,可以找到 MyReal
有一个 module REAL with type t = 'a
的实例。
有没有办法在 OCaml 中对类型的模块进行参数化或从模块中转义类型?基本上,我想编写一些在浮点类型上进行参数化的例程,并且仍然可以访问 (+.)、(-.) 等运算符。当然,我们可以编写一个浮点模块,如
module type REAL = sig
type t
val real : float->t
val (+.) : t->t->t
val (-.) : t->t->t
val ( *. ) : t->t->t
val (/.) : t->t->t
end
它对普通浮点数有一个非常基本的实现
module MyReal : REAL = struct
type t=float
let real x=x
let (+.) x y = x+.y
let (-.) x y = x-.y
let ( *. ) x y = x*.y
let (/.) x y = x/.y
end
然后,我尝试在代码为
的模块中本地使用这个模块let double (type real) (module Real:REAL with type t = real) x =
let open Real in
x+.x
这个函数有我想要的类型
val double : (module REAL with type t = 'a) -> 'a -> 'a = <fun>
但是,如果我运行它,编译器会报错
# double (module MyReal) 1.0;;
Error: This expression has type float but an expression was expected of type
MyReal.t
当然,我们可以使用模块中的注入功能
# double (module MyReal) (MyReal.real 1.0);;
- : MyReal.t = <abstr>
但是结果类型是抽象的而不是浮点数。最终,我想要一种使函数 double return 成为公开类型的方法。如果可能的话,我不想在 REAL 模块中使用另一个函数来转换 t->float
。我希望以某种方式公开实际类型 t
。另外,我想要一种通过在本地使用模块而不是在 REAL
.
您给 MyReal
的类型约束过于严格:MyReal : REAL
。它的类型 t
的实现被约束隐藏了。在使用 MyReal
、double (module MyReal) 1.0
时,类型 t
和 float
的统一失败,因为您隐藏了事实 t = float
.
修复如下:
module MyReal : REAL with type t = float = struct
...
end
但最好的方法是让 OCaml 自己推断 MyReal
的最一般类型:
module MyReal = struct
...
end
在这里,MyReal
和 REAL
的关系不太清楚,但 OCaml 的模块类型足够聪明,可以找到 MyReal
有一个 module REAL with type t = 'a
的实例。