Рассмотрим объектно-ориентированные языки:
Большинство людей, исходящих из объектно-ориентированного программирования, знакомы с общими и интуитивно понятными интерфейсами на разных языках, которые захватывают суть Java Collection
и List
. Collection
относится к коллекции объектов, которая не обязательно имеет естественный порядок/индексацию. A List
представляет собой набор, который имеет естественное упорядочение/индексацию. Эти интерфейсы абстрагируют многие библиотечные структуры данных в Java, как и их эквивалентные интерфейсы на других языках, и для эффективного взаимодействия с большинством библиотечных структур данных требуется глубокое понимание этих интерфейсов.
Переход к Haskell:
Haskell имеет систему типа-типа, которая действует на типы аналогично интерфейсам на объектах. Кажется, что у Haskell есть хорошо спроектированная иерархия классов типов в отношении Функторов, Аппликативных, Монад и т.д., Когда они относятся к функциям типа. Очевидно, они хотят правильные и хорошо абстрагированные типы классов. Однако, когда вы смотрите на многие контейнеры Haskell ( List
, Map
, Sequence
, Set
, Vector
), они почти все имеют очень похожие (или идентичные) функции, но не абстрагируется через классы типов.
Некоторые примеры:
-
null
для проверки "пустоты" -
length
/size
для подсчета элементов -
elem
/member
для включения включения -
empty
и/илиsingleton
для построения по умолчанию -
union
для объединения set -
(\\)
/diff
для заданной разницы -
(!)
/(!!)
для небезопасной индексации (частичная функция) -
(!?)
/lookup
для безопасной индексации (общая функция)
Если я хочу использовать любую из вышеперечисленных функций, но я импортировал два или более контейнера, я должен начать скрывать функции из импортированных модулей или явно импортировать только необходимые функции из модулей или квалифицировать импортированные модули. Но так как все функции обеспечивают одну и ту же логическую функциональность, это просто похоже на хлопот. Если функции были определены из классов типов, а не отдельно в каждом модуле, механика вывода типа компилятора могла бы решить эту проблему. Это также упростило бы переключение базовых контейнеров, пока они разделяли типы классов (т.е. Позволяет просто использовать Sequence
вместо List
для повышения эффективности случайного доступа).
Почему Haskell не имеет класс Collection
и/или Indexable
, чтобы унифицировать и обобщить некоторые из этих функций?