mtl, transformers, monads-fd, monadLib e o paradoxo da escolha

92

O Hackage tem vários pacotes para transformadores monad:

  • mtl : Biblioteca do transformador Monad
  • transformadores : functor de concreto e transformadores monad
  • monads-fd : classes Monad, usando dependências funcionais
  • monads-tf : classes Monad, usando famílias de tipo
  • monadLib : uma coleção de transformadores monad.
  • mtl-tf : Biblioteca de transformadores Monad usando famílias de tipos.
  • mmtl : Biblioteca de transformador Modular Monad
  • mtlx : Biblioteca do transformador Monad com índices de tipo, fornecendo cópias 'gratuitas'.
  • compose-trans : transformadores monádicos composíveis

(e talvez eu tenha perdido alguns)

Qual devemos usar?

mtl é aquele na plataforma Haskell, mas eu continuo ouvindo no reddit que não é legal.

Mas o que há de ruim na escolha, não é apenas uma coisa boa?

Bem, eu vi como, por exemplo, os autores do data-accessor tiveram que fazer tudo isso para atender apenas às escolhas populares:

  • Biblioteca data-accessor-monadLib: funções de acesso para mônadas do monadLib
  • Data-accessor-monads-fd library: use Accessor para acessar o estado na classe monads-fd State monad
  • Data-accessor-monads-tf library: use o Accessor para acessar o estado na família do tipo monads-tf State monad
  • biblioteca data-accessor-mtl: use o Accessor para acessar o estado na classe mtl State monad
  • Data-accessor-transformers library: Use Accessor para acessar o estado em transformadores State monad

Eu imagino que se isso continuar e, por exemplo, vários pacotes concorrentes de Arrow evoluírem, poderemos ver algo como: spoiler-arrow-transformers, spoiler-flechas-monadLib, spoiler-tfArrows-transformers, spoiler-tfArrows-monadLib, ...

E então me preocupo que, se o spoiler do link for bifurcado, o Hackage ficará sem espaço em disco. :)

Questões:

  • Por que existem tantos pacotes de transformadores monad?
  • Por que o mtl [considerado] não é legal?
  • Quais são as principais diferenças?
  • A maioria desses pacotes aparentemente concorrentes foi escrita por Andy Gill e é mantida por Ross Paterson. Isso significa que esses pacotes não são concorrentes, mas funcionam juntos de alguma forma? E Andy e Ross consideram algum de seus próprios pacotes obsoleto?
  • Qual você e eu devemos usar?
Yairchu
fonte
2
Este link me ajudou a entender mtl vs transformadores haskell.org/haskellwiki/Monad_Transformer_Library
Brandon Cook
2
Role para baixo para ver o comentário de @jberryman ! Use mtl ou transfômeros, eles se tornaram compatíveis!
Sophie

Respostas:

70

Vários deles são quase completamente equivalentes:

  • mtlusa extensões GHC, mas transformersé Haskell 98.
  • monads-fde monads-tfsão complementos transformers, usando dependências funcionais e famílias de tipo respectivamente, ambos fornecendo a funcionalidade mtlque está faltando em transformers.
  • mtl-tfé mtlreimplementado usando famílias de tipo.

Então, essencialmente, mtl== transformers++ monads-fd, mtl-tf== transformers++ monads-tf. A portabilidade e modularidade aprimoradas do transformerse de seus pacotes associados é o motivo pelo qual não mtlé legal hoje em dia, eu acho.

mmtle mtlxambos parecem ser semelhantes e / ou baseados em mtl, com diferenças de API e recursos extras.

MonadLibparece ter uma visão bastante diferente sobre os assuntos, mas não estou familiarizado com isso diretamente. Também parece usar muitas extensões GHC, mais do que as outras.

À primeira vista, compose-transparece mais algo de metaprogramação para a criação de transformadores de mônadas. Afirma ser compatível com o Control.Monad.Transque ... acho que significa mtl?

De qualquer forma, sugiro o seguinte algoritmo de decisão:

  • Você precisa de mônadas padrão para um novo projeto? Use transformers& co., Ajude-nos mtla descansar.
  • Você já está usando mtlem um grande projeto? transformersnão é totalmente compatível, mas ninguém vai te matar por não trocar.
  • Um dos outros pacotes fornece funcionalidade incomum de que você precisa? É melhor usá-lo ao invés de enrolar o seu próprio.
  • Ainda insatisfeito? Jogue-os fora, baixe category-extrase resolva todos os problemas do mundo com uma página e meia de código genérico incompreensível e sem sentido abstrato .
CA McCann
fonte
2
if mtl == transformers ++ monads-fd, não poderia ser implementado desta forma? (como uma fase para substituí-lo) que eliminaria a necessidade de ter coisas como data-accessor-mtl
yairchu
2
@yairchu: Bem, sim, mas o que você espera que eu faça a respeito? :) Manter a compatibilidade com versões anteriores nunca é tão fácil quanto parece, e alterar as principais bibliotecas leva tempo, esforço e algum grau de suporte da comunidade. A situação do transformador da mônada é um problema conhecido, mas não acho que seja a principal prioridade de ninguém.
CA McCann
5
@yairchu: isso é basicamente o que está sendo feito. a próxima versão principal do mtl deve ser um esboço que importa transformadores + monads-fd, e a compatibilidade com essa versão será o fator decisivo. As bibliotecas poderão ser atualizadas individualmente para que sejam compatíveis com o mtl 1.1 e 1.2 e, então, os aplicativos serão classificados em qualquer versão instalada ou exigida por sua dependência de biblioteca mais restrita.
Edward KMETT
2
A lista de e-mails das bibliotecas está discutindo atualmente a mudança do MonadIO (e possivelmente do MonadTrans do mtl para a base. Embora, tenha sido pendurado se deve extrair o MonadIO ou um MonadBase mais geral, apesar do fato de que "MonadBase" precisa de MPTCs, fundeps, etc. .
Edward KMETT
27
Pois achei este post extremamente informativo. Pensei em atualizar outros googlers: mtl agora depende de transformadores, monads-fd agora é um esboço sobre mtl. Portanto, use o mtl se precisar dos recursos extras que ele contém ou apenas importe os transformadores se tiver tudo de que você precisa.
jberryman
20

Para o momento? Você provavelmente deve usar mtl. O que está acontecendo é que a transformersbiblioteca está sendo fatorada fora do MTL de uma forma que pode monads-fde monads-tfpode coexistir pacificamente, mas, finalmente, verifique se ainda não era o caso.

Quando isso acontecer, você poderá importar monads-fde transformersobter (quase) a mesma interface, com a exceção de que State, etc. será um apelido para StateT.

Então, eu escreveria para mtl, mas não dependeria do fato de que State, Reader, etc. estão atualmente datacomo serão substituídos por types.

MonadLib é outra alternativa na qual Iavor vem trabalhando, que pode ser usada com segurança porque não compartilha nenhum nome de módulo com os outros, mas que tem um padrão de uso bastante diferente.

Edward KMETT
fonte
4
Coexistir em que sentido? Usado pelo mesmo pacote? Importado para o mesmo módulo? Combinado na mesma pilha de transformadores? Misturar fundeps e TFs me parece uma má ideia, em geral. De qualquer forma, não fiz uso extensivo do transformers& co. ainda, mas não notei nenhum problema além de algumas pequenas diferenças de API vs. mtlao alternar algum código (bastante simples).
CA McCann
4
O problema se resume ao fato de que você só pode carregar um pacote que fornece um determinado módulo. Portanto, se você usa uma biblioteca que usa mtl, mesmo internamente, não pode importar uma alternativa. Atualmente, uma boa porcentagem de hackeamento usa o mtl internamente de alguma forma. Algumas pessoas preferem usar famílias de tipo, e monads-tf lhes dá isso, mas tenha em mente que, no momento, até que a refatoração transformers + monads-fd seja concluída, isso impede que o código use quaisquer bibliotecas que requerem MTL transitivamente . Isso inclui alguns itens muito caros.
Edward KMETT
1
Usar transformadores + mônadas- (tf | fd) evitará, a longo prazo, esse pickle, mas ainda não chegamos lá. Enquanto isso, a preponderância do uso é a favor do mtl. O caminho de atualização parece ser que a próxima versão principal do mtl será redefinida como um stub que importa monads-fd e transformadores. A quebra de versão principal fornece uma boa maneira de declarar em seu arquivo de cabal que você não se importa com a versão que obtém (ou seja, você não se preocupa em State ser um alias de tipo ou um tipo de dados) e uma vez que o aumento de versão principal acontece, então você não precisa se preocupar se todas as bibliotecas que usar compartilham as mesmas tendências.
Edward KMETT
1
Portanto, em última análise, sua experiência até agora é exatamente o que os transformadores / mônadas- (tf | fd) foram projetados para suportar. Mas, o que foi percebido depois que eles foram escritos é que a comunidade é muito ruim em trocar de biblioteca, quando não há um motivo convincente para pular e uma tonelada de motivos legados para ficar. Daí a necessidade de redefinir o mtl e tornar o caminho de atualização claro.
Edward KMETT
Incrível, obrigado pelo esclarecimento detalhado! Obviamente, o código que troquei tinha poucas dependências externas - principalmente ligações FFI, eu acho. Eu também não percebi que os conflitos de nome de módulo eram tão ... invasivos, eu acho? Isso torna as coisas realmente estranhas. :(
CA McCann
16

A fatoração mencionada por Edward Kmett em sua resposta foi concluída no final de 2010. Seu resultado final foi monads-fd , construída sobre transformadores , tornando-se a versão 2 do mtl . Como consequência da onipresença do mtl , as mônadas-tf nunca se popularizaram. No início de 2017, mtl e transformadores são as únicas bibliotecas de transformadores monad que têm uso generalizado.

duplode
fonte