Зачем нам нужны типы сумм?
Представьте себе язык, который не допускает использование нескольких конструкторов значений для типа данных. Вместо того чтобы писать
data Color = White | Black | Blue
мы бы хотели иметь
data White = White
data Black = Black
data Blue = Black
type Color = White :|: Black :|: Blue
где:|:
(здесь это не|
чтобы избежать путаницы с типами суммы) является встроенным оператором объединения типов. Сопоставление с образцом будет работать таким же образом
show :: Color -> String
show White = "white"
show Black = "black"
show Blue = "blue"
Как вы можете видеть, в отличие от копроизведений, это приводит к плоской структуре, поэтому вам не придется иметь дело с инъекциями. И, в отличие от типов сумм, он позволяет произвольно комбинировать типы, что приводит к большей гибкости и детализации:
type ColorsStartingWithB = Black :|: Blue
Я полагаю, что это не будет проблемой для создания рекурсивных типов данных, а также
data Nil = Nil
data Cons a = Cons a (List a)
type List a = Cons a :|: Nil
Я знаю, что типы объединения присутствуют в TypeScript и, возможно, в других языках, но почему комитет по Haskell выбрал ADT вместо них?