Вопрос

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

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

Это было полезно?

Решение

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

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

Другие советы

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

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

  • Синтаксически более тяжелое, но эффективное, надежное и статичное решение состоит в использовании функторов для параметризации вашего кода в структуре данных, которую вы используете. Это упрощает повторное использование кода с различными структурами данных. См. Перевод Маркуса Моттла на OCaml книги Окасаки «Чисто функциональные структуры данных». для некоторых замечательных примеров.

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

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

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

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top