谁能帮我完成 Jason Hickey 书中的练习 12.5?
基本上,问题是如何在实践中避免由于“包含”而导致的以下冲突问题?谢谢。
# module type XSig = sig
type t
val x : t
end;;
# module A : XSig = struct
type t = int
let x = 0
end;;
# module B : XSig = struct
type t = int
let x = 1
end;;
# module C = struct
include A
include B
end;;
最佳答案
我不知道问题的确切含义,但关于您的代码片段,有各种非常不同的方式来解释您要执行的操作。
您目前正在做的是将 A
和 B
密封在两个抽象的、不兼容的签名下,然后尝试将它们混合在一个模块中,结果却产生了名称冲突。
也许您只是想避免名称冲突。当然,最简单的解决方案是不要对 A.t
和 B.t
类型使用相同的名称。那么就可以“不包含B
”:
module C = struct
include A
let x_b = B.x
end
更好的解决方案是使用 OCaml 3.12 破坏性替换签名,with type t := foo
,从模块 B< 中屏蔽类型
:t
/
module C = struct
include A
type u = B.t (* rename B.t into 'u' to avoid name conflict *)
include (B : XSig with type t := u) (* replaces 't' by 'u' *)
end
您可能还希望模块 A
和 B
的类型兼容。在这种情况下,你不能用抽象类型来封装它们。
module type XSig = sig
type t
val x : t
end
module A = struct
type t = int
let x = 0
end
(* if you want to check that A can be sealed by XSig, do it here,
outside the main declaration *)
let _ = (module A : XSig)
module B = struct
type t = int
let x = 1
end
module C = struct
include (A : XSig with type t := int)
include (B : XSig with type t := int)
end
(* module C : sig
val x = int
end *)
在此示例中,A.t
和 B.t
两种类型都被破坏性替换 :=
删除。如果你希望你的模块 C
有一个类型 t
,你可以写:
module C = struct
type t = int
include (A : XSig with type t := t)
include (B : XSig with type t := t)
end
或者,使用非破坏性替换(更改类型定义而不是删除它):
module C = struct
include (A : XSig with type t = int)
include (B : XSig with type t := t)
end
见 manual page for destructive substitution type type t := ...
了解更多详情,和 the one on the classic with type t = ...
construction进行比较。
关于module - 在 OCaml 中包含两个模块时处理类型名称冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11081501/