Сумма типов в ООП

Очень полезная вещь в функциональных языках - пострение новых типов из примитивных с помощью конструкций произведения и суммы типов. И если с произведением типов в обьектно-ориентированных языках все просто: просто делаем два поля нужных типов, то с суммой типов все менее очевидно.

Пусть мы хотим представить тип

MaybeInt = Value Int | Exception String

с помощью класса. Один вариант сделать два поля, но требовать, чтобы одно из них всегда было null. Это влечет очевидные неудобства работы с таким кодом, поэтому такой подход плох.

Каноничной альтернативой будет наследование:

abstract class AbstractMaybeInt class Value extends AbstractMaybeInt(x: Int) class Exception extends AbstractMaybeInt(e: String)

Вместо же pattern-matching-а предлагается использовать полиморфизм:

Функция getOrDefault (Value x) default = x getOrDefault (Exception _) default = default

Будет заменена полиморфной AbstractMaybeInt.getOrDefault(Int), определение которой будет размазано по трем классам (родителю и двум потомкам). То же самое будет при добавлении новой функции, в то время как в функциональном языке функция над суммой типов можно определить в одном месте для всех вариантов или даже пар (двоек, троек...) вариантов типа.

Если же не пользоваться полиморфизмом, то функция над суммой типов должна будет использовать аналог instanceof, а это уже отражение (reflection), которое автор не уважает.

Ну и далее можно вспомнить про всякие паттерны, основывающиеся на наследовании:

Composite T = Leaf T | Node [Composite T]

Fabric = ConcreteFabric1 Fabric1 | ConcreteFabric2 Fabric2 Product = ConcreteProduct1 Product1 | ConcreteProduct2 Product2

И так далее, можно переосмыслить паттерны с функциональной точки зрения. Или (если есть представление о) задуматься о них как о функторе. Впрочем templates (или generics и альтернативы) в принципе уже похожи на функторы.

Ну и наконец, какие-нибудь грамматики, например, регулярных выражений изначально формулируются в контекстно-свободной рекурсивной форме: Regex ::= "a" | "b" | Regex "|" Regex | Regex Regex | Regex "*" | Regex "+"

Что сразу же перекладывается на рекурсивный тип-сумму: Regex = Char | Or Regex Regex | Concat Regex Regex | Star Regex | Plus Regex

Что в свете сказанного выше дает паттерн Интерпретатор