Abbreviating constructor names in Ocaml

喜你入骨 提交于 2019-12-23 11:48:31

问题


I have two modules. One defines a variant type:

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

  (* other stuff *)
end

and I would like to be able to use foo's variants both as constructors and as left-hand-sides in another module

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

but per "referring to named objects" I have to prefix the variant names with a module-path:

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

Is there any way to skip avoid using the module path short of opening and pulling in all the other stuff from A?


回答1:


You can open A locally:

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

or

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

You can define Bar in a submodule so that less things are exposed:

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

For use outside of patterns, you can define a "smart constructor" in B:

let bar m = A.Bar m

ETA: I forgot about the possibility to restate type definition, described in Ashish Argwal's answer: type foo = A.foo = Bar of material | Baz | Boo. Given that you already have type abbreviation in your example, this is the best answer.

There is some work on type-based label disambiguation which could be helpful, but it may not get accepted into the language.




回答2:


In addition to the answers lukstafi gave, you can also re-state the constructors when defining 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


来源:https://stackoverflow.com/questions/13538985/abbreviating-constructor-names-in-ocaml

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!