¿Por qué necesitamos tipos de suma?
Imagine un lenguaje que no permite constructores de valores múltiples para un tipo de datos. En lugar de escribir
data Color = White | Black | Blue
nosotros tendriamos
data White = White
data Black = Black
data Blue = Black
type Color = White :|: Black :|: Blue
dónde:|:
(aquí no es|
para evitar confusiones con los tipos de suma) es un operador de unión de tipo incorporado. La coincidencia de patrones funcionaría de la misma manera
show :: Color -> String
show White = "white"
show Black = "black"
show Blue = "blue"
Como puede ver, en contraste con los coproductos, da como resultado una estructura plana, por lo que no tiene que lidiar con inyecciones. Y, a diferencia de los tipos de suma, permite combinar aleatoriamente los tipos, lo que resulta en una mayor flexibilidad y granularidad:
type ColorsStartingWithB = Black :|: Blue
Creo que no sería un problema construir tipos de datos recursivos también
data Nil = Nil
data Cons a = Cons a (List a)
type List a = Cons a :|: Nil
Sé que los tipos de unión están presentes en TypeScript y probablemente en otros lenguajes, pero ¿por qué el comité de Haskell eligió los ADT sobre ellos?