我的代码有一个奇怪的问题,我真的不知道如何解决它: 我的代码如下:
module type tGraphe = sig
type node
type arc
end;;
module One : tGraphe with type node=int and type arc=int = struct
type noeud=int
type arc=int
end;;
module Two : tGraphe with type node=int and type arc=Empty|Node of(int*int) = struct
type node=int
type arc=Empty|Node of(int*int)
end;;
模块一没有遇到任何问题,但是对于模块二,表明类型为arc的语法错误。 如果有人能解释我如何使用没有“with”的模块类型,我将不胜感激。 已经尝试过了
module Two : tGraphe= struct
type node=int
type arc=Empty|Node of(int*int)
end;;
open Two;;
let z=Empty;;
但它不起作用。
答案 0 :(得分:4)
定义时
type foo = int
type bar = Leaf | Node of int * int
foo
与已存在的类型(int
)的类型同义词之间存在根本区别,bar
引入了 new 类型,引入了新的构造函数Leaf
和Node
,与以前的构造函数不同。
写作时
module M = struct
type foo = int
type bar = Leaf | Node of int * int
end
类型M.foo
等于int
,但类型M.bar
仅等于它自己:它是新的并且没有任何内容可供比较(即使是具有确切类型的类型)相同的构造函数将被视为不同且不兼容)。
在签名中发布M.foo = int
,但不是说M.bar = Leaf | ...
:M.bar
仅等于它自己M.bar
,这是有意义的,并且签名细化M with type bar = M.bar
不会向您提供任何信息。
您的代码中的问题是您坚持使用对使用抽象类型的签名tGraphe
的归属。写jrouquie的代码
type global_arc = Vide | Node of (int*int)
module Two : tGraphe with type noeud = int and type arc = global_arc = struct
type noeud = int
type arc = global_arc
end;;
而不是简单
module Two = struct
type noeud = int
type arc = Vide |Node of(int*int)
end
构造M : S
不仅仅是一个检查。它将主动隐藏从M
输入信息。构造S with type ... = ...
允许隐藏比S
更少的内容。但是如果你想隐藏任何东西,在你的例子中,就是不要使用签名归属!只需写下module M = struct ... end
。
如果你只使用: S
检查你没有错,那么在字段名称和内容中没有任何错误,你可以在旁边使用它作为一个纯粹的检查:
module Two = struct ... end
let () = ignore (module Two : S) (* only a check! *)
SML区分仅检查兼容性的“透明”模块注释和“不透明”模块注释(通常称为密封),强制执行兼容性和隐藏类型信息。 OCaml只有不透明的密封,所以你必须小心不要过度使用它。
PS:在StackOverflow上提问时,如果您的代码是用英语而不是法语编写的话会更好。
答案 1 :(得分:0)
我不确定你想要什么。以下代码有效,但我不知道它是否满足您的需求。
module type tGraphe = sig
type noeud
type arc
end;;
type global_arc = Vide | Node of (int*int)
module Two : tGraphe with type noeud = int and type arc = global_arc = struct
type noeud = int
type arc = global_arc
end;;
let z: Two.arc = Vide;;