Polymorphic variants with number labels are compiled to JS numbers.
See the following example:
type t = [ #1 | #a ]
let is_1 = str => if str == #1 { true } else { false }
let is_a = str => if str == #a { true } else { false }
The JS output for the two functions is:
function is_1(str) {
return str === 1;
}
function is_a(str) {
return str === "a";
}
This is unfortunate if you want to use coercion to convert a poly variant to a string as suggested in the docs: Polymorphic Variant | ReScript Language Manual
Example with the same type:
type t = [ #1 | #a ]
let toStr: t => string
= a => (a :> string)
This throws a type Error: Type t = [#1 | #a] is not a subtype of string
It may be not an issue in most (or all?) cases, since it is easy to use pattern matching for manual type conversion or just add a non-number character to the poly variant, but I was not expecting that labels are treated differently if they consist of digits only.
However, I have two questions that I am curious about:
-
Is there a way to make sure a poly variant consisting only of digits is interpreted as a string by the compiler? I tried
#"1"
or even#\"1"
, but it is all the same as with#1
. -
is there a particular reason why the compiler treats numbered labels differently than other labels in polymorphic variants?