Hai tre scelte.
Piattaforma Haskell
È una possibilità ma non una scelta popolare per molte ragioni che scoprirai a tempo debito se scegli di seguire questa strada. Avrai un'esperienza molto migliore e otterrai molto migliore supporto con Stack o Nix. Quale di queste due persone usa sembra essere principalmente una questione di preferenze personali. Sono bestie diverse ma per un principiante le differenze non saranno immediatamente evidenti, quindi c'è poca speranza che tu possa prendere una "decisione informata". Basta sceglierne uno e rivalutarlo più tardi.
Impila
Questo è ciò che suggerirei a chiunque (non abbia familiarità con Nix) voglia iniziare rapidamente con Haskell. Periodo. Non è necessario installare nulla separatamente, Stack gestirà tutte le cose Haskell per te. Normalmente non usi mai la cabala direttamente con Stack. stack build
usa la cabala internamente ma non devi preoccuparti di questo. Una cosa da notare, Stack non è un gestore di pacchetti. È uno strumento di costruzione. Normalmente non si installa qualsiasi cosa. Tuttavia recupera tutte le dipendenze di cui ha bisogno e le memorizza in ~/.stack
insieme ad altre cose.
Niente
Questo è quello che uso personalmente, quindi potrei essere di parte, ma penso che questa sia la migliore soluzione in generale a lungo termine. L'avvertenza è che c'è una curva di apprendimento piuttosto ripida e ti vengono date molte possibilità di spararti sui piedi quando inizi.
Consiglio vivamente di iniziare con Stack ma di mantenere una mente aperta su Nix mentre il tuo viaggio con Haskell continua.
Ecco una (lunga) risposta alternativa. Nota che consigliavo Stack anche ai principianti, ma da allora ho cambiato idea.
TL;DR: Sia la piattaforma Haskell che un'installazione Stack pura possono fornirti tutto ciò di cui hai bisogno e non ti "perderai" nulla scegliendo l'uno o l'altro. Probabilmente troverai più semplice saltare Stack e installare Haskell Platform utilizzando il programma di installazione Linux "generico", perché viene fornito con tutto ciò di cui hai bisogno e l'installazione corrisponderà più da vicino a quanto descritto nel libro LYAH. Puoi installare Stack in un secondo momento quando esegui uno sviluppo più serio su più progetti. Se preferisci attenersi a un'installazione Stack pura, ti suggerisco di iniziare con un flusso di lavoro "solo progetto globale". In entrambi i casi, puoi utilizzare la "modalità haskell" con alcune correzioni di configurazione suggerite di seguito (inclusa un'impostazione chiave che sarà richiesta se stai lavorando nel progetto globale di un'installazione solo Stack).
Ecco la lunga risposta...
Pila contro piattaforma contro cabala
Il libro LYAH precede Stack, che è certamente il motivo principale per cui non lo menziona. Su haskell.org, consigliano di utilizzare un programma di installazione minimo, Stack o la piattaforma Haskell. Tutti e tre i metodi sono modi perfettamente ragionevoli nel 2018 per creare un ambiente Haskell funzionante. Differiscono sia nel modo in cui scelgono di isolare le diverse versioni del compilatore e/o delle librerie in "sandbox" per il lavoro di sviluppo, sia in quanto installano inizialmente , ma non c'è nulla che "manchi" in nessuno di essi che non possa essere installato su richiesta. A seconda di quale scegli, ci saranno alcune differenze nel tuo flusso di lavoro (vedi sotto).
Sia Stack che Cabal sono gestori di pacchetti combinati e strumenti di compilazione. (Stack ha la capacità aggiuntiva di avviare effettivamente un'intera installazione di Haskell, motivo per cui è anche un metodo di installazione a sé stante.) Mentre lavori con LYAH, non utilizzerai direttamente la funzionalità "strumento di creazione" sui propri progetti. (Le funzionalità di compilazione integrate di GHC sono più che adeguate per la creazione di piccoli progetti multimodulo.) Ti servirà solo la funzionalità di gestione dei pacchetti per installare librerie aggiuntive.
Poiché Stack e Cabal gestiscono i loro pacchetti separatamente, se stai usando Stack, non avrai particolare bisogno di usare Cabal direttamente. Puoi installarlo se vuoi (e infatti Stack fa uso di Cabal per alcune funzionalità esoteriche, come "stack solver", e richiederà che sia installato in quei casi):
$ stack install cabal-install
Ma, anche se questo metterà "cabal" in "$HOME/.local/bin" (e vorrai assicurarti che questo sia nel tuo percorso), scoprirai che devi fare i salti mortali per eseguirlo :
$ stack exec --no-ghc-package-path cabal -- list
e in realtà non fa nulla di utile per quanto riguarda il tuo ambiente Stack.
Aggiornamento: Una nota sul percorso "$HOME/.local/bin". Sembra che lo script di installazione da https://get.haskellstack.org/ possa installare Stack stesso su /usr/local/bin/stack
per impostazione predefinita se non esiste alcuna installazione esistente. Tuttavia, dovrebbe visualizzare un avviso per inserire $HOME/.local/bin
nel tuo cammino. Se aggiorni Stack in futuro con stack upgrade
, installerà la nuova versione di stack
lì, e quella directory verrà utilizzata anche se installi pacchetti che includono binari. Ad esempio, stack install hlint
installerà il programma Haskell Lint hlint
a quella directory. Quindi, è una buona idea averlo nel tuo percorso e da qualche parte prima di /usr/local/bin
.
Cosa manca con Stack
Penso che questo copra le tue prime tre domande. Per ultimo, la cosa principale che ti manca avendo installato Stack invece della piattaforma Haskell è che, in base alla progettazione, Stack non installa realmente nulla a livello globale oltre allo "stack" stesso. Quindi, tutto il tuo lavoro su Haskell, inclusa l'esecuzione dell'interprete Haskell ("ghci") o del compilatore ("ghc"), deve essere svolto all'interno di un ambiente Stack, utilizzando uno specifico comando Stack corrispondente:
$ echo 'main = putStrLn "Hello, world!"' > Hello.hs
$ stack ghc -- Hello.hs
[1 of 1] Compiling Main ( Hello.hs, Hello.o )
Linking Hello ...
$ ./Hello
Hello, world!
$
oppure utilizzando "stack exec" per eseguire un programma generico all'interno di un ambiente Stack appropriato. Ad esempio, a volte può essere utile eseguire una shell Bash sotto stack, dopodiché le cose si comportano come un ambiente della piattaforma Haskell installato a livello globale:
$ stack exec bash
$ ghci
GHCi, version 8.2.2: http://www.haskell.org/ghc/ :? for help
Prelude> :quit
$ ghc -O2 Hello.hs
[1 of 1] Compiling Main ( Hello.hs, Hello.o ) [flags changed]
Linking Hello ...
$ exit
$ ghc
The program 'ghc' is currently not installed. ...
$
L'altra cosa che ti manca è che la piattaforma Haskell installa un intero gruppo di librerie comuni per impostazione predefinita, mentre un nuovo ambiente Stack inizia con quasi nulla (nemmeno il compilatore, prima di eseguire stack setup
). Mentre lavori con LYAH, potresti dover installare periodicamente librerie aggiuntive. Ad esempio, in Input e Output capitolo, gli esempi che utilizzano numeri casuali (modulo System.Random
) richiederà di eseguire:
$ stack install random
e riavvia il tuo interprete.
Consiglio per l'uso della piattaforma Haskell
Poiché Stack è un po 'complicato e non avrai davvero bisogno delle strutture che fornisce all'inizio, potresti trovare la piattaforma Haskell più facile da usare quando inizi. (L'installer "Generico" dovrebbe funzionare bene sulla tua distribuzione.) Viene fornito con tutto ciò che è installato e il modo in cui lo usi corrisponderà più da vicino al modo in cui le cose sono descritte in LYAH. Insieme a haskell-mode
, dovresti avere un ambiente Haskell abbastanza decente.
In generale, non dovrebbero esserci problemi con Stack e la piattaforma Haskell installati fianco a fianco (come evidenziato dal fatto che la piattaforma Haskell in realtà include Pila). Stack manterrà tutto separatamente nella sottodirectory "$HOME/.stack", quindi non ci saranno interferenze tra compilatori o pacchetti o altro. Nota che in questa configurazione utilizzerai cabal
per gestire i pacchetti installati sul lato Platform delle cose, e stack
-- ovviamente -- per gestire i pacchetti lato Stack.
Flusso di lavoro per principianti per un'installazione Pure Stack
Se vuoi continuare con la tua installazione Stack pura, potrei suggerire il seguente flusso di lavoro quando inizi:
Vedrai riferimenti a progetti Stack, creati con "stack new" o "stack init". Evita questi all'inizio e mantieni lo stack "progetto globale". Questo è il progetto implicito che sarà attivo quando esegui "stack" in una directory che non ha un file "stack.yaml" (direttamente o in una directory principale):
$ cd
$ stack path --project-root
/u/buhr/.stack/global-project
$
Quando stai lavorando nel progetto globale (cioè, non da qualche parte sotto un stack.yaml
file), puoi invocare l'interprete e il compilatore con:
$ stack exec ghci
$ stack ghc -- -O2 Hello.hs
ed entrambi avranno accesso a tutte le librerie aggiuntive (pacchetti) che hai installato usando comandi come:
$ stack install random
Aggiornato: Una nota sulla differenza tra stack ghci
e stack exec ghci
. Il primo ha lo scopo di eseguire GHCi nel contesto di un progetto locale (ovvero, lavorando sotto un stack.yaml
file). Passa alcuni flag aggiuntivi per nascondere i pacchetti installati a livello globale e per rendere automaticamente disponibili i moduli dal tuo pacchetto. Quando si lavora nel progetto globale, non credo ci sia alcuna differenza pratica tranne che stack ghci
genera un avviso; e non importa quale usi, dovrai caricare i tuoi moduli in modo esplicito con :load Whatever.hs
. Ci sono un po' più di informazioni sulla differenza in questa pagina della documentazione di Stack, in particolare in fondo dove cerca di spiegare la differenza.
Alla fine, puoi passare a un flusso di lavoro che utilizza i progetti Stack. Ciò comporterà l'utilizzo di stack new
per creare una nuova directory del progetto Stack, stack setup
per installare/collegare una versione del compilatore privato in quella directory, e quindi modificare il xxx.cabal
del progetto file (ed eventualmente il suo stack.yaml
file) per indicare quali pacchetti aggiuntivi sono richiesti, invece di utilizzare stack install
. È tutto un po' complicato quando vuoi solo iniziare a scrivere codice.
Potresti anche vedere un riferimento a Intero, una modalità Emacs progettata specificamente per Stack. Intero è molto carino, ma non funziona molto bene quando si lavora su file nel progetto globale. Tenderà a voler avviare l'interprete nella directory "~/.stack/global-project", il che è abbastanza inutile. (Uso Intero, ma l'ho corretto per comportarsi meglio sotto questo aspetto.)
Configurazione della modalità Haskell (per piattaforma o stack)
Probabilmente è meglio attenersi invece alla "modalità haskell" e pensare a Intero quando inizi a utilizzare progetti non globali. Suggerirei di installare "haskell-mode" da MELPA secondo le istruzioni, ma aggiungendo quanto segue al tuo .emacs
file invece di quanto suggerito nella documentazione:
(require 'haskell)
;; add capability to submit code to interpreter and mark errors
(add-hook 'haskell-mode-hook 'interactive-haskell-mode)
;; add missing keybindings for navigating errors
(define-key interactive-haskell-mode-map (kbd "M-n") 'haskell-goto-next-error)
(define-key interactive-haskell-mode-map (kbd "M-p") 'haskell-goto-prev-error)
(define-key interactive-haskell-mode-map (kbd "C-c M-p")
'haskell-goto-first-error)
;; merge this with your existing custom-set-variables
(custom-set-variables
;; NOTE: include following line to work around haskell-mode
;; bug if using GHC >= 8.2.1.
;; See: https://github.com/haskell/haskell-mode/issues/1553
'(haskell-process-args-stack-ghci
'("--ghci-options=-ferror-spans -fshow-loaded-modules"
"--no-build" "--no-load"))
;; some options suggested in the haskell-mode documentation
'(haskell-process-auto-import-loaded-modules t)
'(haskell-process-log t)
'(haskell-process-suggest-remove-import-lines t)
;; make sure "stack ghci" is used, even in the global project
'(haskell-process-type 'stack-ghci))
L'ho provato con un'installazione Stack pura usando "haskell-mode-20171022.26" e sembra funzionare bene. Posso caricare un nuovo file Haskell nel progetto globale, sottoporlo a una sessione interattiva con "C-c C-l" e sfogliare gli errori evidenziati nel file sorgente con "M-n" e "M-p". (Gli errori vengono visualizzati nel mini-buffer.)
Se invece decidi di utilizzare la piattaforma Haskell, penso che tutta questa configurazione "modalità haskell" si applicherà comunque, tranne per il fatto che dovresti rimuovere l'ultima riga di personalizzazione. (Il valore predefinito haskell-process-type
di auto
sceglierà qualcosa di appropriato.)
Spero di esserti stato d'aiuto!