Подтвердить что ты не робот

Имеет ли OCaml общие функции map()/reduce()?

В Python map() работает с любыми данными, которые следуют за протоколом последовательности. Он делает The Right Thing ^ TM, подавать ли я его строку или список или даже кортеж.

Не могу ли я сделать торт в OCaml? У меня действительно нет другого выбора, кроме как посмотреть на тип коллекции, который я использую, и найти соответствующий List.map или Array.map или Buffer.map или String.map? Некоторые из них даже не существуют! Это то, что я прошу необычно? Мне что-то не хватает.

4b9b3361

Ответ 1

Ближе всего вы доберетесь до этого модуля Enum в Аккумуляторы OCaml в комплекте (ранее Extlib). Enum определяет карты и складки над Enum.t; вам просто нужно использовать преобразование в/из Enum.t для вашего типа данных. Конверсии могут быть довольно легкими, потому что Enum.t ленив.

То, что вы действительно хотите, это типы классов , например Foldable и Functor (который обобщает "карты" ). Библиотеки Haskell определяют экземпляры Foldable и Functor для списков, массивов и деревьев. Другим важным методом является "Scrap Your Boilerplate" подход к универсальному программированию. Поскольку OCaml не поддерживает типы классов или более высокий тип полиморфизма, я не думаю, что вы сможете выразить такие шаблоны в своем типа.

Ответ 2

В OCaml есть два основных решения:

  • Жак Гарриг уже реализовал синтаксически-легкий, но неэффективный подход для многих структур данных несколько лет назад. Вы просто обертываете коллекции в объекты, которые предоставляют метод map. Затем вы можете сделать collection#map, чтобы использовать функцию карты для любого вида коллекции. Это более общее, чем ваши требования, поскольку оно позволяет заменять различные типы структур данных во время выполнения. Однако на практике это не очень полезно, поэтому подход никогда не принимался широко.

  • Синтаксически более тяжелое, но эффективное, надежное и статическое решение - использовать функторы для параметризации вашего кода по используемой структуре данных. Это делает тривиальным повторное использование кода с различными структурами данных. См. Markus Mottl OCaml переводы книги Окасаки "Чисто функциональные структуры данных" для некоторых замечательных примеров.

Если вы не ищете такую ​​власть и просто хотите краткости, то, конечно, вы можете просто создать псевдоним модуля с более коротким именем (например, модуль S = String).

Ответ 3

Проблема состоит в том, что каждый контейнер имеет другое представление и требует, чтобы для его преобразования и преобразования использовался другой код. Вот почему есть отдельные функции. Большинство языков предоставляют какой-то общий интерфейс для контейнеров (например, упомянутый протокол последовательности), поэтому функции, такие как map/reduce, могут быть реализованы абстрактно, но это не делается для типов, о которых вы упомянули.

Ответ 4

Пока вы определяете тип t и val compare (: t- > t- > int) в вашем модуле, Map.Make предоставит вам нужную вам карту.