В чем разница между Cabal и Stack?

106

Вчера я узнал о новом инструменте Haskell под названием Stack . На первый взгляд кажется, что он выполняет ту же работу, что и Кабал. Итак, в чем разница между ними? Является ли стек заменой Кабала? В каких случаях мне следует использовать Stack вместо Cabal? Что может Стэк, чего не может Кабала?

ЖекаКозлов
источник
fpcomplete.com/blog/2015/06/announcing-first-public-beta-stack (короче говоря, он как бы заменяет cabal-installи использует стек в максимально возможной степени - в какой-то момент может произойти некоторая обратная интеграция с cabal-install, и я думаю сообщество не уверено, хорошо это или нет, потому что это может разделить сообщество)
Карстен
Стек AFAIU удобен для быстрой работы над существующим проектом. Если вы начнете что-то с нуля, вам непременно придется использовать кабалу.
mb14
@ mb14 Это не так. Вы можете использовать стек, чтобы начинать проекты с нуля. Фактически, шаблоны стека предоставляют простой способ сделать это.
Сиби
См. Эту короткую статью для хорошего обзора: scs.stanford.edu/16wi-cs240h/labs/stack.html
michid

Ответы:

77

Стек заменяет Кабалу?

Да и нет.

В каких случаях мне следует использовать Stack вместо Cabal? Что может сделать Стек, чего не может Кабала?

По умолчанию Stack использует специально подобранные пакеты стека. . При этом известно, что любые зависимости строятся вместе, избегая проблем конфликта версий (которые, когда они были обычным явлением в опыте Haskell, раньше назывались «адом клики»). В последних версиях Кабала также есть меры по предотвращению конфликтов. Тем не менее, настроить воспроизводимую конфигурацию сборки, в которой вы точно знаете, что будет извлечено из репозиториев, более просто со Stack. Обратите внимание, что есть также положение для использования пакетов без стека, поэтому вы можете продолжать работу, даже если пакет отсутствует в моментальном снимке стека.

Лично мне нравится Stack, и я рекомендую использовать его всем разработчикам Haskell. Их развитие происходит быстро . И у него гораздо лучший UX. И есть вещи, которые делает Stack, чего Кабала еще не предоставляет:

  • Stack даже загружает для вас GHC и хранит его в изолированном месте.
  • Поддержка Docker (что очень удобно для развертывания ваших приложений Haskell)
  • Воспроизводимый сценарий Haskell : вы можете точно определить версию пакета и получить гарантию, что он всегда будет выполняться без каких-либо проблем. ( Cabal также имеет функцию сценария , но полностью обеспечить воспроизводимость с ее помощью не так просто.)
  • Умение делать stack build --fast --file-watch. Он будет автоматически перестроен, если вы измените существующие локальные файлы. Использование его вместе с --pedanticопцией для меня является препятствием.
  • Stack поддерживает создание проектов с использованием шаблонов . Он также поддерживает ваши собственные шаблоны.
  • В стеке есть встроенная поддержка hpack . Он предоставляет альтернативный (IMO, лучший) способ записи файлов кабала с использованием файла yaml, который более широко используется в отрасли.
  • Intero легко работает со Stack .

Есть хороший пост в блоге, объясняющий разницу: Почему Stack не Cabal? Несмотря на то, что за прошедшие с момента публикации статьи годы Кабал эволюционировал таким образом, чтобы преодолеть некоторые из обсуждаемых там проблем, обсуждение целей дизайна и философии, лежащей в основе Stack, остается актуальным.

Сиби
источник
Изменилось ли что-нибудь с момента выхода Cabal 3?
Уильям Руснак,
1
@WilliamRusnack Да, есть. В первую очередь рабочий процесс Cabal по умолчанию теперь включает предотвращение конфликтов зависимостей, хотя стратегия, которую он использует для этого, заметно отличается от стратегии Stack. (@Sibi: Я взял на себя смелость обновить ваш ответ, чтобы он лучше отражал
текущее положение
35

Далее я буду ссылаться на два сравниваемых инструмента: cabal-install и stack . В частности, я буду использовать cabal-install, чтобы избежать путаницы с библиотекой Cabal , которая является общей инфраструктурой, используемой обоими инструментами.

В общих чертах, мы можем сказать, что cabal-install и stack - это фронтенды Cabal . Оба инструмента позволяют создавать проекты Haskell, наборы зависимостей которых могут конфликтовать друг с другом в рамках одной системы. Ключевое различие между ними заключается в том, как они достигают этой цели:

  • По умолчанию, при запросе на сборку проекта cabal-install проверяет зависимости, указанные в его .cabalфайле, и использует решатель зависимостей для определения набора пакетов и версий пакетов, которые ему удовлетворяют. Этот набор взят из Hackage в целом - все пакеты и все версии, прошлые и настоящие. Как только осуществимый план сборки будет найден, выбранная версия зависимостей будет установлена ​​и проиндексирована в базе данных где-нибудь в ~/.cabal. Конфликтов версий между зависимостями можно избежать за счет индексации установленных пакетов в соответствии с их версиями (а также другими соответствующими параметрами конфигурации), чтобы разные проекты могли получать нужные им версии зависимостей, не наступая друг другу на пятки. Это то, чтоДокументация по установке cabal означает "локальные сборки в стиле Nix" .

  • Когда вас попросят создать проект, стек будет смотреть не на Hackage, а на resolverполе stack.yaml. В рабочем процессе по умолчанию в этом поле указывается моментальный снимок стека , который является подмножеством пакетов Hackage с фиксированными версиями, которые, как известно, являются взаимно совместимыми. стек попытается удовлетворить зависимости, указанные в .cabalфайле (или, возможно, в project.yamlфайле - другой формат, та же роль), используя только то, что предоставлено моментальным снимком. Пакеты, устанавливаемые из каждого снимка, регистрируются в отдельных базах данных, которые не мешают друг другу.

Можно сказать, что стековый подход предлагает некоторую гибкость настройки ради простоты, когда дело доходит до указания конфигурации сборки. В частности, если вы знаете, что ваш проект использует, скажем, моментальный снимок LTS 15.3, вы можете перейти на его страницу Stackage и сразу узнать, что версии любого стека зависимостей могут быть извлечены из Stackage. Тем не менее, оба инструмента предлагают функции, которые выходят за рамки основных рабочих процессов, так что, по большому счету, каждый может делать все, что делает другой (хотя, возможно, менее удобным способом). Например, есть способы заморозить точные версии заведомо хорошей конфигурации сборки и решить зависимости со старым состоянием Hackage с помощью cabal -install , и можно потребовать зависимости, не относящиеся к стеку, или переопределить версии пакетов моментальных снимков при использовании стека .

Наконец, еще одно различие между cabal-install и стеком, которое достаточно велико, чтобы его стоит упомянуть в этом обзоре, заключается в том, что стек нацелен на предоставление полной среды сборки с такими функциями, как автоматическое управление установкой GHC и интеграция с Docker . В отличие от этого, cabal-install должен быть ортогонален другим частям экосистемы, и поэтому он не пытается предоставлять такую ​​функцию (в частности, версии GHC должны устанавливаться и управляться отдельно, будь то через дистрибутив Linux. пакеты, ядро платформы Haskell в Windows или инструмент ghcup ).

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

Из того, что я могу почерпнуть из FAQ, кажется, что Stack использует библиотеку Cabal, но не cabal.exeбинарный файл (более известный как cabal-install). Похоже, цель проекта - автоматическая песочница и предотвращение ада зависимостей.

Другими словами, он использует ту же структуру пакета Cabal, он просто предоставляет другой интерфейс для управления этим материалом. (Думаю!)

МатематическаяОрхидея
источник
Кроме того cabal, их исходный код, похоже, также использует docker. Хотя пока не знаю, пользуются ли они этим.
Сиби
@Sibi Да, похоже, что вы можете при желании добавить что-нибудь в Docker, и это должно работать. Я не особо на это смотрел ...
MathematicalOrchid