4 ms·
Sums are tagged unions, whereas unions are more general. Given the types T1 and T2, the union type `U = T1 | T2` includes all values of type T1 and values of t
by spion 4y ago
Sums are tagged unions, whereas unions are more general.
Given the types T1 and T2, the union type `U = T1 | T2` includes all values of type T1 and values of type T2.
A tagged union on the other hand is a new type which does not accept values of neither T1 nor T2 without tagging them with their appropriate tag.
- galaxyLogic 4y agoSo, as you say unions are more general, and thus might be easier to work with? Would there be any benefit for Tagged Unions over "non-tagged" Unions?
- Spivak 4y agoMaybe<T> is a tagged union between T and None. Nullable<T> is an untagged union between T and None.
- choeger 4y agoThere are many benefits of sum types: - Their values can be discriminated at runtime (it's depending on the implementation of union types whether that's possible. In C a union is just a structure large enough to hold all constituents) - You can sum the same type (union(Int, Int) simply is Int) - The tag breaks recursion. You can build recursive sum types because of it, e.g. 'a List = Empty | Cons('a, 'a List)
- earleybird 4y ago> You can sum the same type (union(Int, Int) simply is Int) I'm not sure this is the case. In some cases Union(Int, Int) might be interpreted as a union of Left-Int or Right-Int Then again, my understanding of sum vs union might not be overly precise :-) edit: s/now/not/
- Sharlin 4y agoYou need some sort of a tag if you want to pattern match at runtime, which is the usual use case for tagged unions. Now, a tagged union like type Option a = Some a | None # here Some and None are tags, not types themselves could also be written as an untagged union by using types as tags: type Some a # a wrapper type for an a type None # a unit type type Option a = Some a | None but for that to be useful you still need to be able to check at runtime whether you have a Some or a None… which means that the tags are still there, just hidden by the language. But the more typical use case for untagged unions is different: given a type such as type StringOrInt = String | Int you're not even supposed to be able to check whether you in fact have a String or an Int, rather the language only allows you to use the subset of operations defined for both String and Int. In other words, slightly ironically, the type StringOrInt exposes the intersection of String API and Int API.
- galaxyLogic 4y agoThat's a great answer thanks. So (untagged) Union-type of Haskell really (almost) means INTERSECTION. But it is not an intersection in set-theoretic sense if we think of the values as elements of the sets, because it allows values of both types, but you can only use an intersection of the APIs they provide.