Вопрос по oop – Когда следует использовать объекты в OCaml?

48

Обычно программа OCaml может быть написана с объектами или без них. Когда наиболее выгодно использовать объекты и когда их следует избегать?

Ваш Ответ

1   ответ
72

Как правило, не используйте объекты. Дополнительная сложность, которую они вносят, не так уж часто стоит. Я думаю, что это правило, которое применимо и к другим языкам, но это другая история. По крайней мере, с OCaml можно объективно (без каламбура) сказать, что обычной практикой является не использовать объект, кроме как в редких случаях.

Объект предоставляет пакет из:

  1. A "standard" style for carrying around and using records of functions, with possibly polymorphic types
  2. Facilities for open recursion through self (implementation inheritance)
  3. A structural, extensible product type with row polymorphism (for open object types) and subtyping (for closed object types)

Вы можете использовать любой из них вместе или по отдельности.

По моему опыту, один пункт (1) не особенно полезен для использования объектов: вы можете просто использовать записи функций, и это так же ясно.

Uses Cases of Open Recursive / Inheritance

Пункт (2), напротив, является хорошим оправданием для использования объектно-ориентированного стиля; таким образом он используется Camlp4, например: Camlp4 определяет классы, которые сгибаются по AST, ничего не делая, и вы можете наследовать этот объект обхода, чтобы реализовать желаемое поведение только на тех синтаксических конструкциях, которые вы хотите (и отложить скучный обход твоя мама класс).

Например, можно продлитьCamlp4Ast.map объект, который определяет простую функцию отображения в представлении Camlp4 абстрактных синтаксических деревьев OCaml, просто рекурсивно отображая каждую конструкцию в себя. Если вы хотите, скажем, отобразить все(fun x -> e1) e2 выражения дляlet x = e2 in e1, вы наследуете от этого объекта и переопределяетеexpr метод, обрабатывающий только тот случай, который вы хотите (левая часть - функция), делегирующий другой в унаследованное поведение. Это даст вам объект, который знает, как применить это преобразование ко всей программе, рекурсивно, без необходимости писать какой-либо шаблонный код; и вы можете расширить эту трансформацию дополнительным поведением, если хотите.

Fun with object types

Точка (3) также является оправданием для использования объектов в качестве «расширяемых записей» или «массивов уровня типа»; некоторые библиотеки, использующие объектtypes, но не объект во время выполнения: они используют типы объектов в качестве фантомных типов для переноса информации, получая выгоду от более богатых операций на уровне типов, которые вы можете выполнять над объектами. Кроме того, структурная типизация позволяет различным авторам иметь совместимые типы без сильных зависимостей от общего компонента, определяющего (номинальные) типы, которые они разделяют; объекты были использованы для стандартизации компонентов ввода / вывода, например.

Весьма простой и очень простой пример использования этого - идиоматический способ представления типов, которые имеют много параметров. Вместо того чтобы писать:

type ('name, 'addr, 'job, 'id) person = ....
val me : (string, string, Job.t, Big_int.big_int) person

Вы можете использовать типы объектов как структурные & quot; записи уровня типа & quot; вместо этого написать:

type 'a person = .... constraint 'a = < name:'n; addr:'a; job:'j; id:'i >
val me : < name:string; addr:string; job:Job.t; id:Big_int.big_int > person

Для более сложного использования типов объектов в качестве фантомных типов, вы можете взглянуть наShCaml (доктор) библиотека (где она используется для представления, с какими командами оболочки совместим ввод строки) Алеком Хеллером и Джесси Товом, или моей собственноймакака библиотека (доктор а такжеApi Doc), который использует типы объектов для представления значений SQL (включая информацию об обнуляемости) и типов строк таблицы.
Полиморфные варианты (еще одна продвинутая особенность системы типов OCaml; в предложении отношение между объектами и записями такое же, как отношение между полиморфными вариантами и типами алгебраических сумм). Также использовались в качестве фантомных типов, напримерв этом простом примере Ричардом Джонсом, или проверить достоверность документов HTML вOcsigen фреймворк.

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

Summing up

  • as a base assumption, you're safe with not using objects at all; you should only introduce them in your design if you feel you're missing something, not by default

  • objects are convenient for open recursion / inheritance: refining a behavior that is already defined in the default/boring cases

  • structural typing is occasionally useful when you want to reason on values independently providing a set of features/capacities

Фантастически тщательный ответ. Спасибо большое! Matthew Piziak
@ gasche Я думаю, что-то не так с твоимCamlp4Ast.map ссылка на сайт.
& quot; структурная типизация позволяет различным авторам иметь совместимые типы без сильных зависимостей от общего компонента. & quot; Записи OCaml реализуют структурную типизацию, не так ли?
Нет, записи OCaml являются генеративными (или номинально типизированы): два объявления записей с одинаковыми полями несовместимы. Записи SML являются структурными, но не расширяемыми, что затрудняет эффективную компиляцию / выполнение.
Спасибо, я исправил ссылку.

Похожие вопросы