4 ms·
For many people (myself included), there is a distinction: A sum type is a tagged union. Using ‘|’ for union types and ‘+’ for sum types, the difference is that
by Skeime 6y ago
For many people (myself included), there is a distinction: A sum type is a tagged union. Using ‘|’ for union types and ‘+’ for sum types, the difference is that for a type T the type T | T is simply T again, whereas T + T is two copies of T. That is, given an element x of T + T, I can tell whether x comes from the first or the second copy of T. This means, for example, that T + null always adds a new null element to your type, whereas T | null only adds a null element if none existed before.
If your type system has a different way of turning one type into two different (but isomorphic) types (for example by wrapping them in records with a single field), you can simulate sum types with union types. Hence union types are more general than sum types.
However, in my experience you (almost?) always want sum types anyways. In this case union types being the basic construction tends to be a disadvantage because the basic construct it usually more convenient and therefore gets used. Union types tend to work fine for a while and once you realize that sum types would be better, you have quite a bit of refactoring to do.
- jakobnissen 6y agoThere are also advantages to union types. For example, a Union{T1, T2} can be narrowed to just T1 (by the compiler or the user) without being a breaking change - indeed, the compiler is free to do exactly that in Julia. In contrast, in Rust, the compiler can't look at a function that produces an Option<T>, decide that in this case, it will always return a Some(T), and then have it return a T instead. That happens all the time in Julia. And also, sum types take more boilerplate code to use than union types. In my opinion, sum types are more useful for static analysis, union types are more useful for ease-of-use.
- FeepingCreature 6y agoI was not aware of this distinction.