给出以下界面:
module type Comparable = sig
type t
val compare : t -> t -> int
end
并实施:
open Comparable
module Point : Comparable = struct
type t = {x: float; y: float}
let compare p1 p2 =
match (p1, p2) with
| {x = x1; _}, {x = x2; _} -> int_of_float (x1 -. x2)
end
我如何测试Point
?或者推荐的方法是什么?
我试过了:
let () =
(Printf.printf "%d\n" (Point.compare {x = 1.2; y = 3.4} {x = 3.5; y = 2.1}));
()
但在我的IDE中出现此错误:
Error: Unbound record field x
我该如何制作它以便我可以使用模块中定义的类型而不必诉诸于在模块外部暴露该类型?
我正在考虑某种create_from
方法,它采用对象类型并返回正确的类型。
谢谢
这里的主要问题是您使用Comparable
签名无意中降低了模块的类型精度。
这个签名覆盖type t = {x: float; y: float}
到type t
,这就是为什么你得到
Error: Unbound record field x
一个解决方案是简单地省略签名,让OCaml自己解决
module Point = struct
type t = {x: float; y: float}
let compare p1 p2 =
match (p1, p2) with
| {x = x1; _}, {x = x2; _} -> int_of_float (x1 -. x2)
end
那你可以做
Point.compare {x = 1.2; y = 3.4} {x = 3.5; y = 2.1}
没有任何错误,但是您会收到警告,说明记录类型字段在当前范围内不可见 - 您可以通过指定记录类型来解决此问题:
Point.compare {Point. x = 1.2; y = 3.4} {Point. x = 3.5; y = 2.1}