I can close the ability to create an instance of variant type outside the containing module with a private keyword.
module Ordinary : sig
type t = private X | Y
val x : t
end = struct
type t = X | Y
let x = X
end
I can't create instances of Ordinary.t and the following example is uncompilable:
let f x = if x = Ordinary.X then 1 else 2
Error: Cannot create values of the private type Ordinary.t
But I can match Ordinary.t and the following function works fine:
let f a = function
| Ordinary.X -> 1
| Ordinary.Y -> 2
For me, it is logically correct and I expect the same behavior from polymorphic variants. I created the analogical module for this case too.
module Polymorphic : sig
type t = private [`X | `Y]
val x : t
end = struct
type t = [`X | `Y]
let x = `X
end
But I can't match Polymorphic.t. All my tries with error messages are shown below:
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
Is it possible to match the private polymorphic variant type outside of the declaration container?
If it is - How? If it is not - Why?
The essence of private types is that they are private subtypes of a visible type. In particular values of the private type can be coerced with
:>to the visible type.So, this works for me:
For what it's worth, I think of a polymorphic variant value like
`Xto be pervasive, like the number 1234. So`Xand`Yaren't so much defined inPolymorphicas referenced there. I.e., there is no specialPolymorphic.(`X)value that's different from the unqualified value`X.But there is a type
Polymorphic.tthat's particular to the module. Values of this type can be coerced to[ `X | `Y ]but not the other way around.I hope my way of looking at this isn't too wrong :-) And I hope this is helpful.