Ocaml 模块:如何在上使用联合类型?

Ocaml 模块:如何在上使用联合类型?,ocaml,Ocaml,我的代码中有一个奇怪的问题,我真的不知道如何解决它: 我的代码如下: 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 an

我的代码中有一个奇怪的问题,我真的不知道如何解决它: 我的代码如下:

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;;

但是它不起作用。

我不确定你想要什么。下面的代码可以工作,但我不知道它是否满足您的需要

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;;
当你定义

type foo = int
type bar = Leaf | Node of int * int
foo
,它是已经存在的类型(
int
)的类型同义词,
bar
,它引入了一个新的类型,引入了新的构造函数
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
不会给您任何信息

代码中的问题是,您坚持使用使用抽象类型的签名
tgraph
的归属。通过编写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的类型为…=允许隐藏比使用
S
时少一点的内容。但是,在您的示例中,如果您不想隐藏任何内容,请不要使用签名归属!只需编写
模块M=struct。。。结束

如果您只使用
:S
来检查您没有错,字段名称和内容没有错误,您可以将其作为一个纯粹的检查:

module Two = struct ... end

let () = ignore (module Two : S) (* only a check! *)
SML区别于仅检查兼容性的“透明”模块注释和强制兼容并隐藏类型信息的“不透明”模块注释(通常称为密封)。OCaml只有不透明的密封件,因此必须小心不要过度使用


PS:当问有关StackOverflow的问题时,最好是用英语编写代码,而不是用法语。

是的,它将满足我的所有要求,但如果可以的话,我希望模块中有所有的定义,因此没有像“global_arc”这样的全局类型。但是如果我不能用其他方法,我会保留这个方法。谢谢:)问题是,如果定义两次相同的类型,OCaml编译器会将这两种类型解释为两种不同的类型(即使它们具有相同的定义)。为了防止这种情况并确保这两种类型相同,您必须按照jrouquie的建议预先定义它。感谢所有这些精确性,并对我的法语代码表示抱歉。我完全忘了验证我的代码是否包含一些法语单词。