我可以使用private
关键字关闭在包含模块之外创建变体类型实例的功能。
module Ordinary : sig
type t = private X | Y
val x : t
end = struct
type t = X | Y
let x = X
end
我无法创建的实例,Ordinary.t
并且以下示例无法编译:
let f x = if x = Ordinary.X then 1 else 2
错误:无法创建私有类型 Ordinary.t 的值
但是我可以匹配Ordinary.t
并且以下功能可以正常工作:
let f a = function
| Ordinary.X -> 1
| Ordinary.Y -> 2
对我来说,这在逻辑上是正确的,我希望多态变体具有相同的行为。我也为这个案例创建了类比模块。
module Polymorphic : sig
type t = private [`X | `Y]
val x : t
end = struct
type t = [`X | `Y]
let x = `X
end
但我无法匹配Polymorphic.t
。我所有的错误信息尝试如下所示:
let g a =
match a with
| `X -> 1
| `Y -> 2
let x = g Polymorphic.x
let x = g Polymorphic.x ^^^^^^^^^^^^^
错误:此表达式的类型为 Polymorphic.t,但表达式应为 [< `X | `是]
let x = match Polymorphic.x with
| `X -> 1
| `Y -> 2
| `X -> 1 ^^
错误:此模式匹配 [? `X ] 但预期的模式与 Polymorphic.t 类型的值匹配
let x = match Polymorphic.x with
| Polymorphic.`X -> 1
| Polymorphic.`Y -> 2
| Polymorphic.`X ^
错误:语法错误
let x =
let open Polymorphic in
match x with
| `X -> 1
| `Y -> 2
| `X -> 1 ^^
错误:此模式匹配 [? `X ] 但预期的模式与 Polymorphic.t 类型的值匹配
是否可以在声明容器之外匹配私有多态变体类型?
如果是 - 如何?如果不是 - 为什么?