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

时间:2013-04-16 08:06:23

标签: 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 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;;

但它不起作用。

2 个答案:

答案 0 :(得分:4)

定义时

type foo = int
type bar = Leaf | Node of int * int

foo与已存在的类型(int)的类型同义词之间存在根本区别,bar引入了 new 类型,引入了新的构造函数LeafNode,与以前的构造函数不同。

写作时

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