Они относятся к модульной системе OCaml, но с некоторыми важными отличиями:
Сигнатуры определены на языке (в файлах .hsig ), но в отличие отв OCaml они не создаются на языке.Вместо этого менеджер пакетов контролирует создание экземпляров (в настоящее время это обеспечивает только Cabal).Модули никогда не знают, импортируют ли они абстрактную сигнатуру или фактический модуль.
Модули реализации ничего не знают о сигнатурах и не ссылаются на них напрямую.Любой существующий модуль может реализовать сигнатуру, если определения оказались совместимыми.
Реализация инициируется совпадением имени модуля и имени сигнатуры в зависимостях некоторого модуля компиляции (исполняемый файл, библиотека, набор тестов ...) Когда имена совпадают, происходит процесс, называемый «соответствие сигнатуры», который проверяет совместимость типов и определений.
«Счастливый путь» заключается в том, чтов вашей программе вы зависите от какой-либо библиотеки, имеющей сигнатуру «дыра», а также от другой библиотеки, которая предоставляет модуль реализации с тем же именем.Тогда совпадение подписи происходит автоматически.Если имена не совпадают или нам нужно несколько экземпляров библиотеки, использующей сигнатуры, мы должны переименовать сигнатуры и / или модули в разделе mixins файла Cabal.
Что касается того, почему сигнатуры модулей могут быть полезны, рассмотрим bytestring , наиболее популярную на сегодняшний день библиотеку для обработки двоичных данных в Haskell.Но есть и другие, например, stdio с типом Bytes
.
Предположим, вы пишете свою собственную библиотеку, которая использует двоичные данные, а вы этого не делаетехотите заставить своих пользователей либо в stdio, либо в bytestring .Какой у вас выбор?
- Можно было бы создать что-то вроде
Bytelike
класса и параметризовать все ваши функции с ним.Вам также необходимо добавить параметр типа в каждый тип данных , содержащий байты. - Другой вариант - создать сигнатуру, которая определяет абстрактный тип двоичных данных и все необходимые для него операции.Ваша библиотека будет использовать подпись и останется «неопределенной», пока пользователь не будет зависеть от вашей библиотеки и подходящей реализации при создании своих собственных библиотек.
С точки зрения пользователя, класс типовРешение неудовлетворительное.Пользователь знает, что он хочет использовать либо ByteString
, либо Bytes
, только один из них.Решение не будет зависеть от некоторого флага времени выполнения и останется неизменным на протяжении его программы.И все же ему приходится иметь дело с более сложным API, который напоминает ему об этой уже решенной проблеме на каждом шагу.
Лучше, если он примет решение один раз, запишет его в свой файл .cabal и с тех пор имеет дело с более простым API.