如何在OCaml中重新导出类型?

时间:2015-03-05 04:50:33

标签: module ocaml

我们说我有一个模块A,其定义如下:

type foo = Bar | Baz

模块B

open A

let string_of_foo = function
    | Bar -> "bar"
    | Baz -> "baz"

和模块C

open A
open B

let () =
    let f = Bar in
    print_endline (string_of_foo f)

如何更改模块B以重新导出类型foo,以便我无法打开模块A中的模块C

感谢。

2 个答案:

答案 0 :(得分:6)

B中重新导出内容的一种简单方法是在A中加入B

(* b.ml *)
include A

let string_of_foo = function
| Bar -> "bar"
| Baz -> "baz"

通过使用b.ml编译此ocamlc -c -i b.ml,您可以看到发生了什么:

type foo = A.foo = Bar | Baz
val string_of_foo : foo -> string

foo b.mltype foo = A.foo = Bar | Baz类型的签名可能会让您感到困惑,因为它在OCaml中并不经常出现。它表明类型B.foo不仅具有相同名称的构造函数,而且与A.foo完全等效。

A.foo重新导出B的另一种方法是使用此类型定义:

(* b.ml *)
type foo = A.foo = Bar | Baz

let string_of_foo = function
  | Bar -> "bar"
  | Baz -> "baz"   

当您只想重新显示模块中定义的某些类型时,这非常有用。 (include A重新导出A中定义的所有内容。)

不要忘记写= A.foo,否则B.foo会变成与A.foo不同的类型,即使它具有相同的名称。

使用其中一项更改,您可以直接撰写C而不直接引用A

open B

let () =
    let f = Bar in
    print_endline (string_of_foo f)

答案 1 :(得分:0)

我现在只学习OCaml 3个月,所以我的答案可能不是最好的。但根据我开始的那本书:Real World OCaml打开大量模块并不是一个好主意。在你的情况下,我会使用点符号:

模块B

let string_of_foo = function
  | A.Bar -> "bar"
  | A.Baz -> "baz"

实际上,只需要第一个A.来告诉OCaml您的类型。这个也应该有效:

let string_of_foo = function
  | A.Bar -> "bar"
  | Baz -> "baz"

但我更愿意保持一致。

和模块C

let () =
  let f = A.Bar in
  print_endline (B.string_of_foo f)