我有两个模块。一个定义变体类型:
module A = struct
type foo = Bar of material | Baz | Boo
(* other stuff *)
end
我希望能够将foo
的变体用作构造函数和左侧作为另一个模块
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
但是根据"referring to named objects",我必须在变体名称前加上 module-path :
let f (x : foo) = match x with
| A.Bar m -> A.Bar (g m)
| A.Baz | A.Boo -> x
是否有任何方法可以避免使用open
之前的模块路径并从A
中提取所有其他内容?
答案 0 :(得分: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
。鉴于您的示例中已经有类型缩写,这是最好的答案。
type-based label disambiguation上的某些工作可能会有所帮助,但可能无法接受该语言。
答案 1 :(得分: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