5

我有两个模块。一个定义了一个变体类型:

module A = struct
  type foo = Bar of material | Baz | Boo

  (* other stuff *)
end

我希望能够foo在另一个模块中使用 's 变体作为构造函数和左侧

module B = struct
  type foo = A.foo  (* I can abbreviate A.foo by assigning it a local alias *)

  let f (x : foo) = match x with
    | Bar m       -> Bar (g m)  (* Any way to abbreviate Bar and friends? *)
    | Baz   | Boo -> x
end

但是根据“引用命名对象”,我必须在变体名称前面加上一个模块路径

  let f (x : foo) = match x with
    | A.Bar m         -> A.Bar (g m)
    | A.Baz   | A.Boo -> x

有什么方法可以跳过避免使用缺少opening 的模块路径并从中提取所有其他内容A

4

2 回答 2

9

您可以在本地打开A:

let f (x : foo) = A.(match x with
  | Bar m       -> Bar (g m)
  | Baz   | Boo -> x)

或者

let f (x : foo) =
  let open A in
  match x with
  | Bar m       -> Bar (g m)
  | Baz   | Boo -> x)

您可以Bar在子模块中定义,以便暴露更少的东西:

module A = struct
  module BasicDataAndOps = struct
    type foo = Bar of material | Baz | Boo
  end
  open BasicDataAndOps
  (* other stuff *)
end

module B = struct
  open A.BasicDataAndOps
  ...

为了在模式之外使用,您可以在 B 中定义一个“智能构造函数”:

let bar m = A.Bar m

ETA:我忘记了重述类型定义的可能性,如 Ashish Argwal 的回答中所述:type foo = A.foo = Bar of material | Baz | Boo. 鉴于您的示例中已经有类型缩写,这是最好的答案。

有一些关于基于类型的标签消歧的工作可能会有所帮助,但它可能不会被语言所接受。

于 2012-11-24T10:52:26.573 回答
2

除了 lukstafi 给出的答案之外,您还可以在定义时重新声明构造函数B.foo

module A = struct
  type foo = Bar | Baz
end

module B = struct
  type foo = A.foo = Bar | Baz

let f (x : foo) = match x with
  | Bar -> "bar"
  | Baz -> "baz"

end
于 2012-11-24T23:25:01.677 回答