> unions enable designs that traditional hierarchies can’t express, composing any combination of existing types into a single, compiler-verified contract.
To me that "compiler-verified" maps to "sealed", not "on the fly". Probably.
Their example is:
public union Pet(Cat, Dog, Bird);
Pet pet = new Cat("Whiskers");
- the union type is declared upfront, as is usually the case in c#. And the types that it contains are a fixed set in that declaration. Meaning "sealed" ?
I think your "sealed" is misleading here, as that is used for sum types in similar languages (java).
As the language designer notes in the comments, these are named unions, as opposed to anonymous ones, but they are also working on the latter.
"Sealed" is probably not the correct word to use here, as it would be sealed in both case (it doesn't really make sense to "add" a type to the A | B union). The difference is that you have to add a definition and name it.
var someUser = new { Name = "SideburnsOfDoom", CommentValue = 3 };
What type is `someUser` ? Not one that you can reference by name in code, it is "anonymous" in that regard. But the compiler knows the type.
A type can be given at compile-time in a declaration, or generated at compile-time by the compiler like this. But it is still "Compiler-verified" and not ad-hoc or at runtime.
the type (Dog, Cat) pet seems similar, it's known at compile-time and won't change. A type without a usable name is still a type.
Is this "ad-hoc"? It depends entirely on what you mean by that.
> Cat, Dog and Bird don't have to inherit from the union, you can declare a union of completely random types, as opposed to saying "Animal has three subtypes, no more, no less"
"Animal has three subtypes" is more like the c# "sealed" modifier on a class, meaning that subtyping is not allowed. Except in this case I guess for three existing subtypes.
I mean that Cat, Dog and Bird don't have to inherit from the union, you can declare a union of completely random types, as opposed to saying "Animal has three subtypes, no more, no less", which is what F# does more or less.
To me that "compiler-verified" maps to "sealed", not "on the fly". Probably.
Their example is:
public union Pet(Cat, Dog, Bird);
Pet pet = new Cat("Whiskers");
- the union type is declared upfront, as is usually the case in c#. And the types that it contains are a fixed set in that declaration. Meaning "sealed" ?