Я думаю, что дискриминационные союзы могут быть просто неправильным инструментом для частей этой работы.Только то, что вы пишете функциональный код, не означает, что вы должны выбросить все, что вы знаете.
Дискриминационные союзы являются (в некотором смысле, и есть своего рода предостережением) инверсией наследования (производные типы), мы могли бы назвать их составными типами.
В моделях производных типов гарантированно верно все, что касается родителя в отношении потомков (LSP), в этой модели составных типов все в отношении потомков гарантированно вернородитель. (т.е. вместо «новая собака: животное, новая кошка: животное, это новая собака, кошка: кошка», так что вы получите новую конструкцию всех утверждений, которые верны в отношении кошек и собак. Думайте об этом как о пересечениивсе утверждения как о кошке, так и о собаке.)
Таким образом, возникает вопрос: «Как мы работаем с производными типами в OCaml?». Ну, «O» там означает объект ...
Я бы предложил вам создать объектную модель с производными типами для вашей иерархии фигур, так как у вас есть верхний тип (форма) и нижний тype (пустая форма или ноль).И затем вы создаете свои ADT из этих объектов, поэтому у вас есть
abstract Shape, Circle: Shape, Rectangle: Shape,
Тогда у вас есть
type ShapeProperty = |Фу Формы |Бар прямоугольника |Blah of Circle ;;
Все, что знает о свойстве shape, должно быть в состоянии обработать все три из этих случаев (разумно, поскольку это то, для чего оно у вас есть), а окружность и прямоугольник - это присвоение, совместимое с shape,так что вам не нужно беспокоиться о соглашениях по боксу.
Для чего это стоит, YMMV и т. д. Haskell (другой основной диалект ML, бегающий вокруг) не использует объекты для производных типов, он использует то, что известнокак «классы типов», которые представляют собой наборы свойств / поведений, которые вы «извлекаете из» и «гарантируете реализацию», тем самым позволяя функции принимать конкретный экземпляр класса типов.
В то время как гораздо более функциональныйв своей философии попытка выяснить, что происходит, вызывает у меня головную боль, поскольку обычные абстракции, которые я использую для подобных объектам конструкций, больше не применяются, и мне приходится использовать эти конструкции, которые логически эквивалентны, но семантически существенно более необычны (хотя я знаю, чтомного людей, которые используют йони имеют большой успех, так что это могут быть только мои собственные ошибки).
Обратите внимание на предостережение, поскольку тегированные объединения помечены, все, что вам нужно сделать, это гарантировать семантическое действие для всех тегов.Это действие может быть «неудачным», почему вы даете мне один из них, я понятия не имею, что с ним делать ».Проблема, как вы заметили в этой конструкции, заключается в том, что при этом вы теряете много действительно крутых аспектов безопасности типов.Например, вы пишете функцию, которая принимает параметр int, а затем, если для этого параметра ничего не указывается, вы бросаете исключение, ну почему вы сказали, что знаете, как обрабатывать параметр int?