Ayer me enteré de una nueva herramienta de Haskell llamada Stack . A primera vista, parece que hace el mismo trabajo que Cabal. Entonces, ¿cuál es la diferencia entre ellos? ¿Es stack un reemplazo para Cabal? ¿En qué casos debería usar Stack en lugar de Cabal? ¿Qué puede hacer Stack que Cabal no pueda?
haskell
cabal
haskell-stack
ZhekaKozlov
fuente
fuente
cabal-install
y usa stackage tanto como sea posible; podría haber alguna integración posterior en cabal-install en algún momento y creo que la comunidad no está segura de si esto es algo bueno o no, porque podría dividir a la comunidad)Respuestas:
Si y no.
Stack utiliza los paquetes de apilamiento seleccionados de forma predeterminada . Siendo así, se sabe que las dependencias se construyen juntas, evitando problemas de conflicto de versiones (que, cuando eran algo común en la experiencia de Haskell, solían conocerse como "infierno de cabal"). Las versiones recientes de Cabal también tienen medidas para prevenir conflictos. Aún así, configurar una configuración de compilación reproducible en la que sepa exactamente qué se extraerá de los repositorios es más sencillo con Stack. Tenga en cuenta que también existe una disposición para el uso de paquetes que no son apilables, por lo que puede comenzar incluso si un paquete no está presente en la instantánea de apilamiento.
Personalmente, me gusta Stack y recomendaría a todos los desarrolladores de Haskell que lo usen. Su desarrollo es rápido . Y tiene una UX mucho mejor. Y hay cosas que Stack hace que Cabal aún no proporciona:
stack build --fast --file-watch
. Esto se reconstruirá automáticamente si cambia los archivos locales presentes. Usarlo junto con la--pedantic
opción es un factor decisivo para mí.Hay una buena publicación en el blog que explica la diferencia: ¿Por qué Stack no es Cabal? Si bien Cabal, en los años intermedios desde esa publicación, ha evolucionado para superar algunos de los problemas discutidos allí, la discusión de los objetivos de diseño y la filosofía detrás de Stack sigue siendo relevante.
fuente
En lo que sigue, me referiré a las dos herramientas que se comparan como cabal-install y stack . En particular, usaré cabal-install para evitar confusiones con la biblioteca Cabal , que es una infraestructura común utilizada por ambas herramientas.
En términos generales, podemos decir que cabal-install y stack son interfaces de Cabal . Ambas herramientas permiten crear proyectos Haskell cuyos conjuntos de dependencias pueden entrar en conflicto entre sí dentro de los límites de un solo sistema. La diferencia clave entre ellos radica en cómo abordan este objetivo:
De forma predeterminada, cabal-install , cuando se le pida que cree un proyecto, observará las dependencias especificadas en su
.cabal
archivo y usará un solucionador de dependencias para encontrar un conjunto de paquetes y versiones de paquetes que lo satisfagan. Este conjunto se extrae de Hackage en su conjunto: todos los paquetes y todas las versiones, pasadas y presentes. Una vez que se encuentra un plan de compilación factible, la versión elegida de las dependencias se instalará e indexará en una base de datos en algún lugar~/.cabal
. Los conflictos de versiones entre dependencias se evitan indexando los paquetes instalados de acuerdo con sus versiones (así como otras opciones de configuración relevantes), de modo que diferentes proyectos puedan recuperar las versiones de dependencia que necesitan sin pisar los dedos de los demás. Este arreglo es lo queLa documentación de cabal-install significa "compilaciones locales al estilo Nix" .Cuando se le pida que cree un proyecto, la pila , en lugar de ir a Hackage, mirará el
resolver
campo destack.yaml
. En el flujo de trabajo predeterminado, ese campo especifica una instantánea de Stackage , que es un subconjunto de paquetes de Hackage con versiones fijas que se sabe que son compatibles entre sí. stack luego intentará satisfacer las dependencias especificadas en el archivo (o posiblemente el archivo - formato diferente, la misma función) utilizando solo lo que proporciona la instantánea. Los paquetes instalados de cada instantánea se registran en bases de datos independientes, que no interfieren entre sí..cabal
project.yaml
Podríamos decir que el enfoque de pila intercambia cierta flexibilidad de configuración por sencillez cuando se trata de especificar una configuración de compilación. En particular, si sabe que su proyecto usa, digamos, la instantánea de LTS 15.3, puede ir a su página Stackage y conocer, de un vistazo, las versiones de cualquier pila de dependencias que podrían extraer de Stackage. Dicho esto, ambas herramientas ofrecen características que van más allá de los flujos de trabajo básicos para que, en general, cada una pueda hacer todo lo que hace la otra (aunque posiblemente de una manera menos conveniente). Por ejemplo, hay formas de congelar versiones exactas de una buena configuración de compilación conocida y de resolver dependencias con un estado antiguo de Hackage con cabal-install, y es posible requerir dependencias que no sean de Stackage o anular versiones de paquetes de instantáneas mientras se usa stack .
Por último, otra diferencia entre cabal-install y stack que es lo suficientemente grande como para ser mencionado en esta descripción general es que stack tiene como objetivo proporcionar un entorno de compilación completo, con características como la administración automática de la instalación de GHC y la integración de Docker . En contraste, cabal-install está destinado a ser ortogonal a otras partes del ecosistema, por lo que no intenta proporcionar este tipo de función (en particular, las versiones de GHC deben instalarse y administrarse por separado, ya sea a través de la distribución de Linux paquetes, Haskell Platform Core en Windows o la herramienta ghcup ).
fuente
Por lo que puedo deducir de las preguntas frecuentes, parece que Stack usa la biblioteca Cabal, pero no el
cabal.exe
binario (más correctamente conocido como cabal-install). Parece que el objetivo del proyecto es el sandboxing automático y evitar el infierno de la dependencia.En otras palabras, usa la misma estructura de paquete Cabal, solo proporciona una interfaz diferente para administrar estas cosas. (¡Yo creo que!)
fuente
cabal
, su código fuente también parece estar usandodocker
. Aunque no sé si lo usan todavía.