In quanto segue, farò riferimento ai due strumenti confrontati come cabal-install e stack . In particolare, userò cabal-install per evitare confusione con la libreria Cabal , che è l'infrastruttura comune utilizzata da entrambi gli strumenti.
In generale, possiamo dire che cabal-install e stack sono front-end di Cabal . Entrambi gli strumenti consentono di creare progetti Haskell i cui insiemi di dipendenze potrebbero entrare in conflitto tra loro entro i confini di un singolo sistema. La differenza fondamentale tra loro sta nel modo in cui affrontano questo obiettivo:
Per impostazione predefinita, cabal-install , quando viene chiesto di compilare un progetto, esaminerà le dipendenze specificate nel suo .cabal
file e utilizzerà un risolutore di dipendenze per individuare un insieme di pacchetti e versioni di pacchetti che lo soddisfano. Questo set è tratto da Hackage nel suo insieme: tutti i pacchetti e tutte le versioni, passate e presenti. Una volta trovato un piano di compilazione fattibile, la versione scelta delle dipendenze verrà installata e indicizzata in un database da qualche parte in ~/.cabal
. I conflitti di versione tra le dipendenze vengono evitati indicizzando i pacchetti installati in base alle loro versioni (così come ad altre opzioni di configurazione rilevanti), in modo che i diversi progetti possano recuperare le versioni delle dipendenze di cui hanno bisogno senza pestarsi reciprocamente. Questa disposizione è ciò che ildocumentazione di cabal-install significa "build locali in stile Nix" .
Quando viene chiesto di creare un progetto, lo stack , invece di andare su Hackage, esaminerà il resolver
campo di stack.yaml
. Nel flusso di lavoro predefinito, quel campo specifica un'istantanea Stackage , che è un sottoinsieme di pacchetti Hackage con versioni fisse note per essere reciprocamente compatibili. stack tenterà quindi di soddisfare le dipendenze specificate nel file (o forse il file - formato diverso, stesso ruolo) utilizzando solo ciò che è fornito dallo snapshot. I pacchetti installati da ogni snapshot vengono registrati in database separati, che non interferiscono tra loro..cabal
project.yaml
Potremmo dire che l' approccio dello stack scambia una certa flessibilità di configurazione con semplicità quando si tratta di specificare una configurazione di build. In particolare, se sai che il tuo progetto utilizza, ad esempio, l'istantanea LTS 15.3, puoi andare alla sua pagina Stackage e sapere, a colpo d'occhio, le versioni di qualsiasi stack di dipendenze potrebbero estrarre da Stackage. Detto questo, entrambi gli strumenti offrono funzionalità che vanno oltre i flussi di lavoro di base in modo che, in generale, ciascuno possa fare tutto ciò che fa l'altro (anche se forse in un modo meno conveniente). Ad esempio, ci sono modi per congelare versioni esatte di una buona configurazione di build nota e per risolvere le dipendenze con un vecchio stato di Hackage con cabal-install, ed è possibile richiedere dipendenze non Stackage o sovrascrivere le versioni del pacchetto snapshot durante l'utilizzo dello stack .
Infine, un'altra differenza tra cabal-install e stack, che è abbastanza grande da essere degna di nota in questa panoramica, è che lo stack mira a fornire un ambiente di compilazione completo, con funzionalità come la gestione automatica dell'installazione GHC e l' integrazione Docker . Al contrario, cabal-install è pensato per essere ortogonale ad altre parti dell'ecosistema, e quindi non cerca di fornire questo tipo di funzionalità (in particolare, le versioni GHC devono essere installate e gestite separatamente, sia tramite la distribuzione Linux packages, Haskell Platform Core in Windows o lo strumento ghcup ).
cabal-install
e usa lo stackage il più possibile - potrebbe esserci qualche integrazione a ritroso in cabal-install ad un certo punto e penso la comunità non è sicura se questa sia una buona cosa o meno, perché potrebbe dividere la comunità)