mtl, transformers, monads-fd, monadLib et le paradoxe du choix

92

Hackage propose plusieurs packages pour les transformateurs monades:

  • mtl : bibliothèque de transformateurs Monad
  • transformateurs : foncteur béton et transformateurs monades
  • monads-fd : classes Monad, utilisant des dépendances fonctionnelles
  • monads-tf : classes Monad, utilisant des familles de types
  • monadLib : une collection de transformateurs monad .
  • mtl-tf : bibliothèque de transformateurs Monad utilisant des familles de types.
  • mmtl : bibliothèque de transformateurs modulaires Monad
  • mtlx : bibliothèque de transformateurs Monad avec index de types, fournissant des copies «gratuites».
  • compose-trans : transformateurs monades composables

(et peut-être que j'en ai manqué)

Lequel utiliserons-nous?

mtl est celui de la plate-forme Haskell, mais j'entends constamment sur reddit que ce n'est pas cool.

Mais ce qui est mauvais dans le choix de toute façon, n'est-ce pas juste une bonne chose?

Eh bien, j'ai vu comment, par exemple, les auteurs de l'accès aux données ont dû faire tout cela pour répondre uniquement aux choix populaires:

  • bibliothèque data-accessor-monadLib: fonctions d'accesseur pour les monades de monadLib
  • bibliothèque data-accessor-monads-fd: utilisez Accessor pour accéder à l'état dans la classe de monade d'état monads-fd
  • bibliothèque data-accessor-monads-tf: utilisez Accessor pour accéder à l'état dans la famille de types monades d'état monads-tf
  • bibliothèque data-accessor-mtl: utilisez Accessor pour accéder à l'état dans la classe mtl State monad
  • bibliothèque data-accessor-transformers: utilisez Accessor pour accéder à l'état dans les transformateurs State monad

J'imagine que si cela continue et que par exemple plusieurs packages Arrow concurrents évoluent, nous pourrions voir quelque chose comme: spoonklink-arrows-transformers, spoonklink-arrows-monadLib, spoonklink-tfArrows-transformers, spoonklink-tfArrows-monadLib, ...

Et puis je crains que si spoonklink se fourche, Hackage manquera d'espace disque. :)

Des questions:

  • Pourquoi y a-t-il autant de packages de transformateurs monades?
  • Pourquoi mtl [considéré] n'est-il pas cool?
  • Quelles sont les principales différences?
  • La plupart de ces packages apparemment concurrents ont été écrits par Andy Gill et sont maintenus par Ross Paterson. Cela signifie-t-il que ces packages ne sont pas concurrents mais fonctionnent plutôt ensemble d'une manière ou d'une autre? Et Andy et Ross considèrent-ils l'un de leurs propres packages comme obsolète?
  • Lequel devrais-tu et moi utiliser?
Yairchu
la source
2
Ce lien m'a aidé à comprendre mtl vs transformers haskell.org/haskellwiki/Monad_Transformer_Library
Brandon Cook
2
Faites défiler vers le bas pour le commentaire @jberryman ! Utilisez mtl ou transfomers, ils sont devenus compatibles!
Sophie

Réponses:

70

Un certain nombre d'entre eux sont presque complètement équivalents:

  • mtl utilise les extensions GHC, mais transformers c'est Haskell 98.
  • monads-fdet monads-tfsont des add-ons à transformers, utilisant respectivement des dépendances fonctionnelles et des familles de types, tous deux fournissant les fonctionnalités mtlmanquantes de transformers.
  • mtl-tfest mtlréimplémenté à l'aide de familles de types.

Donc, essentiellement, mtl== transformers++ monads-fd, mtl-tf== transformers++ monads-tf. La portabilité et la modularité améliorées de transformerset de ses packages associés expliquent pourquoi ce mtln'est pas cool de nos jours, je pense.

mmtlet les mtlxdeux semblent similaires et / ou basés sur mtl, avec des différences d'API et des fonctionnalités supplémentaires.

MonadLibsemble avoir une vision assez différente des choses, mais je ne la connais pas directement. Semble également utiliser beaucoup d'extensions GHC, plus que les autres.

En un coup d'œil, cela compose-transressemble plus à une métaprogrammation pour créer des transformateurs monades. Il prétend être compatible avec Control.Monad.Translequel ... je suppose que ça veut dire mtl?

En tout cas, je suggère l'algorithme de décision suivant:

  • Avez-vous besoin de monades standard pour un nouveau projet? Utilisez transformers& co., Aidez-nous à nous mtlreposer.
  • Utilisez-vous déjà mtldans un grand projet? transformersn'est pas complètement compatible, mais personne ne vous tuera pour ne pas avoir changé.
  • L'un des autres packages fournit-il des fonctionnalités inhabituelles dont vous avez besoin? Autant l'utiliser plutôt que de rouler le vôtre.
  • Toujours insatisfait? Jetez-les tous, téléchargez category-extraset résolvez tous les problèmes du monde avec une page et demie de code générique incompréhensible et abstrait à couper le souffle.
CA McCann
la source
2
si mtl == transformers ++ monads-fd, ne pourrait-il pas être implémenté de cette manière? (en tant que phase de remplacement) qui éliminerait le besoin d'avoir des trucs comme data-accessor-mtl
yairchu
2
@yairchu: Eh bien oui, mais qu'espérez-vous que je fasse à ce sujet? :) Maintenir la compatibilité ascendante n'est jamais aussi facile qu'il y paraît, et changer les bibliothèques de clés demande du temps, des efforts et un certain soutien de la communauté. La situation du transformateur monad est un problème connu, mais je ne pense pas que ce soit la priorité absolue de quiconque.
CA McCann
5
@yairchu: c'est essentiellement ce qui se fait. la prochaine version majeure de mtl devrait être un stub qui importe les transformers + monads-fd, et la compatibilité avec cette version sera le facteur décisif. Les bibliothèques pourront ensuite être mises à jour individuellement afin qu'elles soient compatibles avec mtl 1.1 et 1.2, puis les applications seront classées dans la version installée ou requise par leur dépendance de bibliothèque la plus restrictive.
Edward KMETT
2
La liste de diffusion des bibliothèques discute actuellement du déplacement de MonadIO (et peut-être de MonadTrans de mtl vers la base. Cependant, il a été suspendu sur l'opportunité d'extraire MonadIO ou une MonadBase plus générale malgré le fait que "MonadBase" a besoin de MPTC, de fundeps, etc. .
Edward KMETT
27
Depuis que j'ai trouvé ce post extrêmement instructif. Je pensais mettre à jour d'autres googleurs: mtl dépend maintenant des transformateurs, monads-fd est maintenant un stub autour de mtl. Utilisez donc mtl si vous avez besoin des bonus supplémentaires dont il dispose, ou importez simplement des transformateurs s'il a tout ce dont vous avez besoin.
jberryman le
20

Pour le moment? Vous devriez probablement utiliser mtl. Ce qui se passe, c'est que la transformersbibliothèque est exclue de la MTL d'une manière qui monads-fdet monads-tfpeut coexister pacifiquement, mais enfin vérifier que ce n'était pas encore le cas.

Lorsque cela se produit, vous pourrez importer monads-fdet transformersobtenir (presque) la même interface, sauf que State, etc. sera un alias pour StateT.

J'écrirais donc mtl, mais je ne me fierais pas au fait que l'État, le lecteur, etc. sont actuellement datatels qu'ils seront remplacés par l' typeart.

MonadLib est une autre alternative sur laquelle Iavor a travaillé, qui peut être utilisée en toute sécurité car elle ne partage aucun nom de module avec les autres, mais qui a un modèle d'utilisation assez différent.

Edward KMETT
la source
4
Coexister dans quel sens? Utilisé par le même package? Importé dans le même module? Combiné dans la même pile de transformateurs? Mélanger les fonds et les TF me semble une mauvaise idée, en général. Quoi qu'il en soit, je n'ai pas beaucoup utilisé transformers& co. encore, mais n'a pas remarqué de problèmes autres que quelques différences mineures d'API par rapport mtlau changement de code (assez simple).
CA McCann
4
Le problème vient du fait que vous ne pouvez charger qu'un seul paquet qui fournit un module donné. Donc, si vous utilisez une bibliothèque qui utilise mtl, même en interne, vous ne pouvez pas importer d'alternative. Actuellement, un pourcentage sain de piratage utilise le mtl en interne d'une manière ou d'une autre. Un certain nombre de personnes préfèrent utiliser des familles de types, et monads-tf leur donne cela, mais gardez à l'esprit que pour le moment, jusqu'à ce que le refactoring des transformers + monads-fd soit terminé, cela empêche le code d'utiliser toutes les bibliothèques qui nécessitent de manière transitoire MTL . Cela inclut des articles assez gros.
Edward KMETT
1
L'utilisation de transformers + monads- (tf | fd) évitera à long terme ce cornichon, mais nous n'en sommes pas encore là. En attendant, la prépondérance de l'usage est en faveur de mtl. Le chemin de mise à niveau semble être que la prochaine version majeure du mtl sera redéfinie en tant que stub qui importe les monads-fd et les transformateurs. La rupture de version majeure fournit un bon moyen d'indiquer dans votre fichier cabal que vous ne vous souciez pas de la version que vous obtenez (c'est-à-dire que vous ne vous souciez pas que State soit un alias de type ou un type de données) et une fois que ce changement de version majeur se produit, alors vous n'avez pas besoin de vous soucier si toutes les bibliothèques que vous utilisez partagent toutes les mêmes préjugés.
Edward KMETT
1
Donc, en fin de compte, votre expérience jusqu'à présent est exactement ce que les transformateurs / monads- (tf | fd) sont conçus pour prendre en charge. Mais, ce qui a été réalisé après leur rédaction, c'est que la communauté est vraiment très mauvaise pour changer de bibliothèque, alors qu'il n'y a pas de raison impérieuse de sauter et une tonne de raisons héritées de rester. D'où la nécessité de redéfinir mtl et de rendre le chemin de mise à niveau clair.
Edward KMETT
Génial, merci pour la clarification détaillée! De toute évidence, le code que j'ai changé avait peu de dépendances externes - principalement des liaisons FFI, je pense. Je n'ai pas non plus réalisé que les conflits de nom de module étaient que ... envahissants, je suppose? Cela rend les choses vraiment gênantes. :(
CA McCann
16

L'affacturage mentionné par Edward Kmett dans sa réponse a été achevé à la fin de 2010. Son résultat final a été monads-fd , construit sur des transformateurs , devenant la version 2 de mtl . En raison de l'omniprésence de mtl , les monades-tf n'ont jamais vraiment fait leur chemin . Au début de 2017, MTL et les transformateurs sont les seules bibliothèques de transformateurs monades à être largement utilisées.

duplode
la source