Что такое сигнатуры модулей в Haskell? - PullRequest
5 голосов
/ 09 марта 2019

Я недавно обнаружил функцию Haskell, которая называется "сигнатуры модуля".Как я обнаружил, они помещаются в .hsig файлы и начинаются с ключевого слова signature вместо module.Примерный синтаксис такого файла может выглядеть следующим образом:

signature Str where

data Str
empty :: Str
append :: Str -> Str -> Str

Однако я не представляю, как и почему их можно использовать.Не могли бы вы объяснить, какие проблемы они решают и как правильно их использовать?

Они сильно напоминают мне систему модулей, которую можно увидеть в OCaml ( ссылка ), которая также имеетподписи модулей и отдельные реализации, но я не могу решить, насколько близки эти две концепции.Это как-то связано?

Ответы [ 2 ]

4 голосов
/ 09 марта 2019

Они относятся к модульной системе OCaml, но с некоторыми важными отличиями:

  • Сигнатуры определены на языке (в файлах .hsig ), но в отличие отв OCaml они не создаются на языке.Вместо этого менеджер пакетов контролирует создание экземпляров (в настоящее время это обеспечивает только Cabal).Модули никогда не знают, импортируют ли они абстрактную сигнатуру или фактический модуль.

  • Модули реализации ничего не знают о сигнатурах и не ссылаются на них напрямую.Любой существующий модуль может реализовать сигнатуру, если определения оказались совместимыми.

  • Реализация инициируется совпадением имени модуля и имени сигнатуры в зависимостях некоторого модуля компиляции (исполняемый файл, библиотека, набор тестов ...) Когда имена совпадают, происходит процесс, называемый «соответствие сигнатуры», который проверяет совместимость типов и определений.

«Счастливый путь» заключается в том, чтов вашей программе вы зависите от какой-либо библиотеки, имеющей сигнатуру «дыра», а также от другой библиотеки, которая предоставляет модуль реализации с тем же именем.Тогда совпадение подписи происходит автоматически.Если имена не совпадают или нам нужно несколько экземпляров библиотеки, использующей сигнатуры, мы должны переименовать сигнатуры и / или модули в разделе mixins файла Cabal.


Что касается того, почему сигнатуры модулей могут быть полезны, рассмотрим bytestring , наиболее популярную на сегодняшний день библиотеку для обработки двоичных данных в Haskell.Но есть и другие, например, stdio с типом Bytes.

Предположим, вы пишете свою собственную библиотеку, которая использует двоичные данные, а вы этого не делаетехотите заставить своих пользователей либо в stdio, либо в bytestring .Какой у вас выбор?

  • Можно было бы создать что-то вроде Bytelike класса и параметризовать все ваши функции с ним.Вам также необходимо добавить параметр типа в каждый тип данных , содержащий байты.
  • Другой вариант - создать сигнатуру, которая определяет абстрактный тип двоичных данных и все необходимые для него операции.Ваша библиотека будет использовать подпись и останется «неопределенной», пока пользователь не будет зависеть от вашей библиотеки и подходящей реализации при создании своих собственных библиотек.

С точки зрения пользователя, класс типовРешение неудовлетворительное.Пользователь знает, что он хочет использовать либо ByteString, либо Bytes, только один из них.Решение не будет зависеть от некоторого флага времени выполнения и останется неизменным на протяжении его программы.И все же ему приходится иметь дело с более сложным API, который напоминает ему об этой уже решенной проблеме на каждом шагу.

Лучше, если он примет решение один раз, запишет его в свой файл .cabal и с тех пор имеет дело с более простым API.

1 голос
/ 09 марта 2019

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...