mtl, трансформаторы, monads-fd, monadLib и парадокс выбора

91

В Hackage есть несколько пакетов для преобразователей монад:

  • mtl : библиотека преобразователей монад
  • трансформаторы : Конкретный функтор и монадные трансформаторы
  • monads-fd : классы монад, использующие функциональные зависимости
  • monads-tf : классы монад, использующие семейства типов
  • monadLib : Коллекция преобразователей монад.
  • mtl-tf : библиотека преобразователей монад, использующая семейства типов.
  • mmtl : Модульная библиотека преобразователей Monad
  • mtlx : библиотека преобразователей монад с указателями типов, предоставляющая «бесплатные» копии.
  • compose-trans : Составные преобразователи монад

(а может я что-то пропустил)

Какой из них использовать?

mtl - это тот, что есть на платформе Haskell, но я постоянно слышу на Reddit, что это не круто.

Но что в любом случае плохого в выборе, разве это не хорошо?

Что ж, я видел, как, например, авторам средства доступа к данным пришлось сделать все это, чтобы удовлетворить только популярные варианты:

  • библиотека data-accessor-monadLib: функции доступа для монад monadLib
  • Библиотека data-accessor-monads-fd: используйте Accessor для доступа к состоянию в monads-fd Класс монады состояния
  • Библиотека data-accessor-monads-tf: используйте Accessor для доступа к состоянию в monads-tf Семейство типов монад состояний
  • библиотека data-accessor-mtl: используйте Accessor для доступа к состоянию в классе монады состояния mtl
  • библиотека data-accessor-transformers: используйте Accessor для доступа к состоянию в преобразователях State monad

Я предполагаю, что если это будет продолжаться и, например, появятся несколько конкурирующих пакетов Arrow, мы можем увидеть что-то вроде: Spoklink-стрелки-трансформеры, Spoklink-стрелки-monadLib, Spoklink-tfArrows-transformers, Spokeklink-tfArrows-monadLib, ...

И потом я беспокоюсь, что если ложка будет разветвлена, у Hackage закончится место на диске. :)

Вопросы:

  • Почему так много пакетов трансформаторов монад?
  • Почему mtl [считается] не крутым?
  • В чем основные отличия?
  • Большинство этих, казалось бы, конкурирующих пакетов были написаны Энди Гиллом и поддерживаются Россом Патерсоном. Означает ли это, что эти пакеты не конкурируют, а скорее работают вместе? И считают ли Энди и Росс какие-либо из своих пакетов устаревшими?
  • Какой из них следует использовать нам с вами?
Яирчу
источник
2
Эта ссылка помогла мне понять mtl vs transformers haskell.org/haskellwiki/Monad_Transformer_Library
Брэндон Кук
2
Прокрутите вниз до комментария @jberryman ! Используйте мтл или трансформеры, они стали совместимы!
Софи

Ответы:

70

Некоторые из них почти полностью эквивалентны:

  • mtlиспользует расширения GHC, но transformersэто Haskell 98.
  • monads-fdи monads-tfявляются надстройками transformers, использующими функциональные зависимости и семейства типов, соответственно, и обеспечивают функции mtl, отсутствующие в transformers.
  • mtl-tfявляется mtlпереписана с использованием семей типа.

По сути, mtl== transformers++ monads-fd, mtl-tf== transformers++ monads-tf. Я думаю, что улучшенная переносимость, модульность transformersи связанные с ним пакеты - вот почему mtlв наши дни это не круто.

mmtlи mtlxоба кажутся похожими и / или основанными на mtlразличиях API и дополнительных функциях.

MonadLibкажется, у меня совсем другой взгляд на вещи, но я не знаком с этим напрямую. Также, похоже, использует много расширений GHC, больше, чем другие.

На первый взгляд compose-transэто больше похоже на метапрограммирование для создания преобразователей монад. Он утверждает, что совместим с Control.Monad.Transкакими ... я думаю, значит mtl?

Во всяком случае, я бы предложил следующий алгоритм решения:

  • Вам нужны стандартные монады для нового проекта? Используйте transformers& co., Помогите нам mtlупокоиться.
  • Вы уже используете mtlв большом проекте? transformersне полностью совместим, но никто не убьет вас за то, что вы не переключитесь.
  • Предоставляет ли один из других пакетов необычные функции, которые вам нужны? С таким же успехом можно использовать его, а не катать самостоятельно.
  • Все еще недовольны? Выкиньте их все, скачайте category-extrasи решите все мировые проблемы с помощью полутора страниц непонятного абстрактного бреда потрясающе универсального кода.
CA McCann
источник
2
если mtl == transformers ++ monads-fd, разве это не может быть реализовано таким образом? (как этап на пути к его замене), который избавит от необходимости иметь такие вещи, как data-accessor-mtl
yairchu
2
@yairchu: Ну да, но что ты думаешь, что я буду делать? :) Поддержание обратной совместимости никогда не бывает таким простым, как кажется, а изменение ключевых библиотек требует времени, усилий и некоторой степени поддержки сообщества. Ситуация с преобразователем монад - известная проблема, но я не думаю, что это чья-то первоочередная задача.
CA McCann,
5
@yairchu: вот что в основном и делается. следующая основная версия mtl должна быть заглушкой, которая импортирует трансформаторы + monads-fd, и совместимость с этой версией будет решающим фактором. После этого библиотеки смогут обновляться по отдельности, чтобы они были совместимы как с mtl 1.1, так и с 1.2, а затем приложения будут привязаны к той версии, которая установлена ​​или требуется их наиболее жесткой зависимостью от библиотеки.
Эдвард КМЕТТ
2
В списке рассылки библиотек в настоящее время обсуждается перенос MonadIO (и, возможно, MonadTrans из mtl в базу). Хотя было решено извлечь MonadIO или более общую MonadBase, несмотря на то, что для «MonadBase» требуются MPTC, fundeps и т. Д. .
Эдвард KMETT
28
Поскольку я нашел этот пост чрезвычайно информативным. Я думал, что обновлю других гуглеров: mtl теперь зависит от трансформаторов, monads-fd теперь является заглушкой вокруг mtl. Так что используйте mtl, если вам нужны дополнительные полезности, или просто импортируйте трансформаторы, если в нем есть все, что вам нужно.
jberryman
19

На момент? Вам, вероятно, следует использовать mtl. То , что происходит в том , что transformersбиблиотека быть вынесена из MTL в моде , что monads-fdи monads-tfможет мирно сосуществовать, но в последней проверки , который не был еще случай.

Когда это произойдет, вы сможете импортировать monads-fdи transformersполучить (почти) тот же интерфейс, за исключением того State, что и т.д. будет псевдонимом для StateT.

Поэтому я бы написал mtl, но не полагался бы на тот факт, что State, Reader и т. Д. В настоящее время dataзаменены на types.

MonadLib - это еще одна альтернатива, над которой работает Iavor, которую можно безопасно использовать, поскольку она не разделяет имена модулей с другими, но имеет совершенно другой шаблон использования.

Эдвард КМЕТТ
источник
4
В каком смысле сосуществовать? Используется одним и тем же пакетом? Импортирован в тот же модуль? Объединены в один трансформатор? В общем, смешивание fundeps и TF кажется мне плохой идеей. В любом случае, я не очень широко использовал transformers& co. еще, но не заметил никаких проблем, кроме некоторых незначительных отличий API от mtlпри переключении некоторого (довольно простого) кода.
CA McCann
4
Проблема сводится к тому, что вы можете загрузить только один пакет, который предоставляет данный модуль. Поэтому, если вы используете библиотеку, которая использует mtl, даже для внутреннего использования, вы не можете импортировать альтернативу. В настоящее время значительный процент хакеров каким-то образом использует mtl для внутренних целей. Некоторые люди предпочитают использовать семейства типов, и monads-tf дает им это, но имейте в виду, что на данный момент, пока не будет завершен рефакторинг transformers + monads-fd, это блокирует этот код от использования любых библиотек, которые транзитивно требуют MTL. . Это включает в себя несколько довольно крупных билетов.
Эдвард КМЕТТ
1
Использование трансформаторов + монад- (tf | fd) в долгосрочной перспективе позволит избежать этого рассола, но мы еще не достигли этого. Между тем преобладание использования в пользу mtl. Путь обновления выглядит так, что следующая основная версия mtl будет переопределена как заглушка, которая импортирует monads-fd и трансформаторы. Разрыв основной версии предоставляет хороший способ заявить в вашем кабальном файле, что вам все равно, какую версию вы получите (т. Е. Вас не волнует, что State является псевдонимом типа или типом данных), и как только произойдет это изменение основной версии, тогда вам не нужно беспокоиться о том, разделяют ли все используемые вами библиотеки одни и те же предубеждения.
Эдвард КМЕТТ
1
Итак, в конечном итоге ваш опыт - это именно то, что трансформаторы / монады- (tf | fd) предназначены для поддержки. Но после того, как они были написаны, стало ясно, что сообщество ужасно плохо переключает библиотеки, когда нет веской причины для прыжка и массы устаревших причин остаться. Следовательно, необходимо переопределить mtl и сделать путь обновления понятным.
Эдвард КМЕТТ
Отлично, спасибо за подробное разъяснение! Очевидно, что у кода, который я переключил, было мало внешних зависимостей - я думаю, в основном это привязки FFI. Я также не понимал, что конфликты имен модулей были настолько ... инвазивными, я полагаю? Это действительно делает вещи неловкими. :(
CA McCann
16

Вычленение на множители, о котором Эдвард Кметт упоминает в своем ответе, было завершено в конце 2010 года. Его конечным результатом стал monads-fd , построенный на трансформаторах , ставший версией 2 mtl . Вследствие повсеместного распространения mtl , monads -tf так и не прижился. По состоянию на начало 2017 года mtl и трансформаторы - единственные библиотеки преобразователей монад, которые получили широкое распространение.

дуплодировать
источник