如何在包含模块之外匹配私有多态变体类型?
How to match private polymorphic variant type outside of containing module?
我可以使用 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
Error: Cannot create values of the private type 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
^^^^^^^^^^^^^
Error: This expression has type Polymorphic.t but an expression was expected of type
[< `X | `Y ]
let x = match Polymorphic.x with
| `X -> 1
| `Y -> 2
| `X -> 1
^^
Error: This pattern matches values of type [? `X ]
but a pattern was expected which matches values of type Polymorphic.t
let x = match Polymorphic.x with
| Polymorphic.`X -> 1
| Polymorphic.`Y -> 2
| Polymorphic.`X
^
Error: Syntax error
let x =
let open Polymorphic in
match x with
| `X -> 1
| `Y -> 2
| `X -> 1
^^
Error: This pattern matches values of type [? `X ]
but a pattern was expected which matches values of type Polymorphic.t
是否可以匹配声明容器外的私有多态变体类型?
如果是——怎么样?如果不是 - 为什么?
私有类型的本质是它们是可见类型的私有子类型。特别是私有类型的值可以用 :>
强制转换为可见类型。
所以,这对我有用:
# match (Polymorphic.x :> [`X|`Y]) with
| `X -> 1
| `Y -> 2
;;
- : int = 1
对于它的价值,我认为像 `X
这样的多态变体值是普遍存在的,例如数字 1234。所以 `X
和 `Y
没有那么多定义在 Polymorphic
中引用。即,没有与不合格值 `X
.
不同的特殊 Polymorphic.(`X)
值
但是有一个 type Polymorphic.t
是模块特有的。可以将此类型的值强制转换为 [ `X | `Y ]
,但反之则不行。
我希望我看待这个问题的方式不会太错误 :-) 我希望这对您有所帮助。
我可以使用 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
Error: Cannot create values of the private type 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 ^^^^^^^^^^^^^
Error: This expression has type Polymorphic.t but an expression was expected of type [< `X | `Y ]
let x = match Polymorphic.x with
| `X -> 1
| `Y -> 2
| `X -> 1 ^^
Error: This pattern matches values of type [? `X ] but a pattern was expected which matches values of type Polymorphic.t
let x = match Polymorphic.x with
| Polymorphic.`X -> 1
| Polymorphic.`Y -> 2
| Polymorphic.`X ^
Error: Syntax error
let x =
let open Polymorphic in
match x with
| `X -> 1
| `Y -> 2
| `X -> 1 ^^
Error: This pattern matches values of type [? `X ] but a pattern was expected which matches values of type Polymorphic.t
是否可以匹配声明容器外的私有多态变体类型?
如果是——怎么样?如果不是 - 为什么?
私有类型的本质是它们是可见类型的私有子类型。特别是私有类型的值可以用 :>
强制转换为可见类型。
所以,这对我有用:
# match (Polymorphic.x :> [`X|`Y]) with
| `X -> 1
| `Y -> 2
;;
- : int = 1
对于它的价值,我认为像 `X
这样的多态变体值是普遍存在的,例如数字 1234。所以 `X
和 `Y
没有那么多定义在 Polymorphic
中引用。即,没有与不合格值 `X
.
Polymorphic.(`X)
值
但是有一个 type Polymorphic.t
是模块特有的。可以将此类型的值强制转换为 [ `X | `Y ]
,但反之则不行。
我希望我看待这个问题的方式不会太错误 :-) 我希望这对您有所帮助。