34 KiB
La Guida
Questa è la strada che raccomando per imparare Haskell.
Per chi non parla italiano
Un consiglio: non preoccupatevi se non capite qualcosa alla prima lettura. Andate avanti.
Comunità
Il nostro canale IRC è #haskell-beginners
su Freenode.
Un client web per IRC è disponibile qui.
La mailing list di Haskell.
Linee guida per la comunità
Leggete il post di Chris Done sull'insegnamento. Siate gentili e cortesi. Comportamenti crudeli o meschini spaventano gli altri e fanno passare la voglia di partecipare.
Crtitiche facili, in cui non mettete impegno, beneficiano soltanto voi e non la persona che le riceve.
Non descrivete niente con parole come "facile" o "banale". Chi legge si sentirà stupido perché le cose che definite come triviali possono aver richiesto molto impegno. Spesso chi impara lentamente impara più profondamente, è una cosa che dovremmo perseguire!
Non fate finta di essere sorpresi quando qualcuno vi dice che non sa qualcosa. Lo farete sentire soltanto stupido e non avrete ottenuto niente a parte sentirvi più furbi.
Non dite beh-in realtà. Come quando qualcuno dice che qualcosa è quasi, ma non completamente corretta, e voi cominciate a dire, "beh, in realtà…" e poi fate una piccola correzione. È molto irritante, specialmente quando la correzione non è pertinente alla conversazione che state avendo. Questo non significa che l'Hacker School non si preoccupi della verità o che non ci interessi essere precisi. Ma questi modi di fare sono quasi sempre più una questione di pavoneggiamento che altro.
Non dite agli altri cosa devono fare. Se qualcuno sta completando un esercizio non dovreste interromperlo continuamente con consigli. Lasciate che trovi la sua strada a meno che non lo chieda esplicitamente. Evitare interruzioni è uno degli obiettivi fondamentali di #haskell-beginners.
Non lasciate spazio a sottili "ismi". Razzismo, sessismo, omofobia, transfobia, e altri tipi di pregiudizi non saranno tollerati.
Linee guida tratte dal manuale della Hacker School . Grazie per averle rese pubbliche.
Cosa sono Haskell, GHC e Cabal?
Haskell è un linguaggio di programmazione, e come potete leggere nei report, la versione più recente è stata rilasciata nel 2010. Il report è disponibile online: report.
GHC
GHC è il modo più classico per lavorare in Haskell. Include un compilatore, un REPL (interprete), un gestore automatico di pacchetti e librerie, ed altro.
Cabal
Cabal è software per gestire i progetti haskell e risolvere le dipendenze. È lo strumento che vi permetterà di installare i pacchetti, tipicamente ciascuno nel proprio sandbox.
Cabal è equivalente a Bundler di Ruby, pip di Python, NPM di Node, Maven, etc. GHC gestisce i pacchetti indipendentemente, Cabal sceglie quale versione installare.
Il set-up dei tool
Ubuntu
Questo PPA è ottimo ed è quello che uso su tutte le mie macchine linux, sia per i build automatici che per lo sviluppo.
Istruzioni specifiche:
$ sudo apt-get update
$ sudo apt-get install python-software-properties # v12.04 and below
$ sudo apt-get install software-properties-common # v12.10 and above
$ sudo add-apt-repository -y ppa:hvr/ghc
$ sudo apt-get update
$ sudo apt-get install cabal-install-1.20 ghc-7.8.3 happy-1.19.4 alex-3.1.3
Aggiungete poi la seguente linea al vostro $PATH
(bash_profile, zshrc, bashrc, etc):
~/.cabal/bin:/opt/cabal/1.20/bin:/opt/ghc/7.8.3/bin:/opt/happy/1.19.4/bin:/opt/alex/3.1.3/bin
Opzionale: Potete anche aggiungere .cabal-sandbox/bin
al vostro path. Il codice che state sviluppando attivamente sarà così disponibile dalla linea di comando. Questo funziona solo quando la directory in cui siete è un sandbox di cabal.
Debian
Repository GHC per debian stable
Se utilizzate Debian stable, è meglio usare il repository http://deb.haskell.org/. Per usarlo:
- Aggiungete la linea
deb http://deb.haskell.org/stable/ ./
a/etc/apt/sources.list
## Aggiungi la chiave per evitare warning
$ GET http://deb.haskell.org/deb.haskell.org.gpg-key | apt-key add -
$ sudo apt-get update
$ sudo apt-get install ghc-7.8.3 happy alex cabal-install
Usando Ubuntu PPA
Se non state usando Debian stable, le stesse istruzioni che abbiamo indicato per Ubuntu fuzionano, ma dovrete eseguire un comando in più. Immediatamente dopo che il comando
sudo add-apt-repository -y ppa:hvr/ghc
lanciate:
$ sudo sed -i s/jessie/trusty/g /etc/apt/sources.list.d/hvr-ghc-jessie.list
Per altre versioni di Debian dovete solo rimpiazzare tutte le occorrenze di jessie
con il nome della versione che state utilizzando nel comando di cui sopra.
Se per qualche ragione il file /etc/apt/sources.list.d/hvr-ghc-jessie.list
non dovesse esistere, allora /etc/apt/sources.list
dovrebbe contenere una linea come questa:
deb http://ppa.launchpad.net/hvr/ghc/ubuntu jessie main
Rimpiazzate quindi in quella linea jessie
con trusty
.
Compilazione manuale
Potete seguire questa guida scritta per Mac OS X:
Note:
- Quando configurate ghc settate il prefisso appropriato
- Invece di prendere il binario di
cabal-install
, scaricate il codice sorgente e lanciate lo scriptbootstrap.sh
.
Fedora 21
Per installare Haskell 7.8.4 dal repository non ufficiale (Fedora 22+ lo includerà ufficialmente):
$ sudo yum-config-manager --add-repo \
> https://copr.fedoraproject.org/coprs/petersen/ghc-7.8.4/repo/fedora-21/petersen-ghc-7.8.4-fedora-21.repo
$ sudo yum install ghc cabal-install
Come affermato in petersen/ghc-7.8.4 copr page questo ghc non può essere installato insieme con il ghc di Fedora/EPEL.
Arch Linux
Per installare Haskell dal repository ufficiale su Arch Linux, lanciate
$ sudo pacman -S cabal-install ghc happy alex haddock
Gentoo
Su Gentoo, potete installare i singoli componenti della Haskell Platform
attraverso Portage. Se usate ACCEPT_KEYWORDS=arch
(invece che
ACCEPT_KEYWORDS=~arch
), Portage installerà versioni più vecchie di Haskell. Tenendone di conto, se usate ACCEPT_KEYWORDS=arch
, aggiungete le seguenti linee a /etc/portage/package.keywords
.
dev-haskell/cabal-install
dev-lang/ghc
Una volta fatto quello, lanciate:
$ emerge -jav dev-lang/ghc dev-haskell/cabal-install
Gentoo include una versione "stabile" (leggi: vecchia) di cabal-install
nell'albero di Portage, quindi vorrete usare cabal-install
per installare la versione più recente. I backslash sono intenzionali.
$ \cabal update # I backslash
$ \cabal install cabal-install # sono intentionali
Adesso avete installato cabal a livello globale con portage, e localmente nella vostra home directory con cabal-install
. Il prossimo passo è assicurarsi che quando lanciate cabal
in un terminale, la vostra shell lanci la versione più recente che è nella vostra home directory. Aggiugete le linee seguenti nel file di configurazione della vostra shell:
PATH=$PATH:$HOME/.cabal/bin
alias cabal="$HOME/.cabal/bin/cabal"
Se non sapete quale shell avete, è molto probabile che la vostra shell sia Bash. Se usate Bash, il file che dovete editare è ~/.bashrc
. se usate Z-shell, il file è ~/.zshrc
. Potete lanciare il seguete comando per sapere qual'è la vostra shell.
echo $SHELL | xargs basename
Io uso zsh, quindi il comando restituisce zsh
quando lo lancio.
Una volta fatto tutto questo, dovrete installare i tool addizionali alex
e happy
.
$ cabal install alex happy
Congratulazioni! Adesso avete una installazione di Haskell funzionante!
Mac OS X
10.9
Installate GHC per Mac OS X, che include GHC e Cabal. La guida vi darà istruzioni su come installare GHC e Cabal nel vostro path una volta che avete copiato la .app da qualche parte sul disco fisso.
10.6-10.8
Eseguite l'installazione dei binari come scritto qui sotto usando questo tarball.
Windows
- L' installer minimo per windows di GHC
è in grado di compilare
network
e altro. È tecnicamente in beta ma dovrebbe funzionare per gli scopi di chiunque legga questa guida.
Non dimenticatevi di lanciare l'installer come amministratore, dato che è richiesto l'accesso alla directory di sistema 'Programmi'.
Altri utenti Linux
Scaricate l'ultima distribuzione binaria di cabal e ghc:
Corsi primari
Il corso cis194 di Yorgey
Seguite questo per primo, è la strada che raccomando per il primo approccio ad Haskell.
Disponibile online.
Il corso di Brent Yorgey è il migliore che ho trovato finora. Questo corso ha valore non solo perché vi rende in grado di scrivere codice Haskell basilare ma anche perché vi aiuterà a comprendere i parser combinators.
L'unica ragione per cui non dovreste cominciare con cis194 è se non siete programmatori o se non avete molta esperienza. In questo caso, suggerisco di iniziare con il libro di Thompson e poi passate a cis194.
Il corso NICTA
Questo è il corso che raccomando dopo cis194 di Yorgey
Disponibile su github qui.
Questo vi darà esperienza nell'implementare direttamente le astrazioni introdotte in cis194. Questi esercizi sono fondamentali per sviluppare confidenza con gli usi comuni di Functor/Applicative/Monad/etc. in Haskell. La raccomandazione principale di questa guida è seguire cis194 e poi NICTA: questo è il percorso che seguo per insegnare Haskell a tutti.
Corso Supplementare cs240h
Fornisce più materiale sugli argomenti intermedi
Disponibile online.
Questo è il corso online di Bryan O'Sullivan tratto dal corso che insegna a Stanford. Se non sapete chi è, date un'occhiata alla metà delle librerie che qualsiasi progetto Haskell richiede e ci troverete il suo nome. Sa avete già seguito il corso di Yorgey sono particolarmente rilevanti i moduli sui phantom types, il flusso di controllo delle informazioni, le estensioni del linguaggio, le concorrenza, le librerie pipes e lenses.
Materiale di riferimento per i tre corsi
Learn You a Haskell for Great Good (LYAH) e Real World Haskell (Grazie bos!) sono disponibili online.
Raccomando RWH come referenza (è un libro spesso). I capitoli sul parsing e sulle monadi sono ottimi per arrivare a capire l'utilità delle monadi stesse. Alcuni hanno detto che è piaciuto molto. Probabilmente è un buon follow-up per imparare gli idiomi in modo pratico, una volta che avete imparato le cose essenziali di Haskell?
Cosa fa quel syntactic sugar <-
/ do
/ sulle list comprehension?
Eccellente articolo.
Per capire list e fold
Per imparare alcune Typeclass di uso comune
Utile per capire Functor
, Applicative
, Monad
, Monoid
e altre Typeclass di uso comune, ma anche informazioni specifiche di Hask e di Teoria delle Categorie:
Capire i messaggi di errore più comuni di Haskell
Laziness, strictness, guarded recursion
-
Il libro di Marlow sul parallelismo e la concorrenza ha una delle migliori introduzioni alla laziness e alla normal form che abbia trovato. Avrete bisogno di materiale in più se non acquisite i concetti subito.
-
Domanda su Stack Overflow 'Does haskell have laziness?'
-
La presentazione di Johan Tibell su reasoning about laziness.
Breve dimostrazione
let a = 1 : a -- guarded recursion, (:) è lazy su di esso si può usare pattern matching.
let (v : _) = a
> v
1
> head a -- head a == v
1
let a = 1 * a -- non guarded, (*) è strict
> a
*** Exception: <<loop>>
IO
-
Haddocks for System.IO.Unsafe.unsafePerformIO Leggete la documentazione e le note sulla implementazione di unsafeDupablePerformIO
Commento da un thread di Reddit, di glaebhoerl
Nota interessante: GHC deve nascondere la rappresentazione dello state token dietro un tipo IO astratto perché lo state token deve sempre essere usato linearmente (non duplicato o droppato), ma il type system non può garantire che questo accada. Clean, un altro linguaggio lazy come Haskell, ha 'uniqueness types' (sono come i linear types e possibilmente diversi per aspetti di cui non sono a conoscenza), e espongono World-passing direttamente e forniscono una monade IO (non astratta) solo per convenienza.
Monadi and monad transformers
Non cominciate a imparali finché non capite typeclass, Monoid, Functor e Applicative!
Implementate per conto vostro le monadi della libreria standard (List, Maybe, Cont, Error, Reader, Writer, State) per capirle meglio. Poi potreste provare a scrivere un interprete monadico per piccole espressioni facendo riferimento all'articolo Monad Transformers Step by Step (menzionata in 'monad transformers' qui sotto).
Scrivere diversi interpreti cambiando solo la monade per cambiare la semantica può aiutarvi a capire in che cosa consiste.
- Questa presentazione di Tony dà un eccellente motivazione per imparare i monad transformers, le slide.
Poi reimplementate Control.Monad
. Funzioni come mapM
o sequence
sono buone opportunità per fare esercizio e scrivere codice monadico generico.
Il corso NICTA può essere usato come guida a questo scopo, che include anche lo scrivere la vostra typeclass Applicative.
Referenza:
Monad transformers
-
Monad transformers step-by-step (attenzione il codice riportato è datato).
Testare, test, specifiche, testing generativo e di proprietà
-
Questo tutorial di Kazu Yamamoto è fantastico.
-
Simple-Conduit: Un'ottima libreria per imparare in modo semplice come funziona lo streaming IO in generale; la conoscenza è trasferibile a librerie più complesse come Pipes e Conduit
Parsing in Haskell
-
Tutorial sui Parser combinator per Haskell, usando Parsec
Parsare e generare JSON
Aeson è la soluzione di parsing JSON standard in haskell. Disponibile su hackage e github.
Algoritmi per grafi e strutture dati
-
Il pacchetto fgl gli algoritmi puramente funzionali per trovare la strada più breve.
-
Il pacchetto graphs.
Ambienti di sviluppo
Emacs
Vim
Sublime Text
Lavorare con Cabal
Linee guida di Cabal
Prima dell'introduzione dei sandbox, gli utenti Haskell incappavano nel problema definito Cabal Hell (Inferno di Cabal). Se non utilizzate una sandbox, cabal installerà il pacchetto nel vostro user package-db. Questa non è in genere una buona idea, fatta l'eccezione per alcuni pacchetti di base come Cabal, alex e happy. Nient'altro dovrebbe essere installato nel package-db dell'utente né tanto meno a livello globale, a meno che non sappiate cosa state facendo.
Alcune raccomandazioni per non cadere nel Cabal Hell sono disponibili qui.
Per provare un pacchetto o cominciare un progetto, iniziate lanciando
cabal sandbox init
in una nuova directory.
In poche parole:
-
Quando installate nuovi pacchetti, create nuovi progetti o pre-esistenti, o cominciate esperimenti usate sempre i sandbox.
-
Usate
cabal repl
invece per iniziare una istanza di ghci come project-scoped
Questo approccio basato sui sandbox dovrebbe scamparvi dai problemi relativi alle dipendenze dei paccheti, ma è incompatibile con il modo in cui la Haskell Platform fornisce i pacchetti binari. Se state imparando Haskell e non capite come funzionano ghc-pkg e Cabal, evitate la haskell platform, ed usate invece le istruzioni all'inizio della guida.
Stackage
Tutti gli utenti (di solito utenti di Yesod) che hanno problemi di build potrebbero provare ad utilizzare Stackage.
- Un buon riassunto di Stackage è qui.
Secondo l'opinione dell'autore, Stackage è in genere più utile di cabal freeze
.
Hoogle e Haddock
Ricerca di codice mediante type signature
Il motore di ricerca Hoogle può cercare per tipo.
Per esempio, guardate i risultati della ricerca per (a -> b) -> [a] -> [b]
qui.
Lo trovate anche su fpcomplete qui.
Anche Hayoo (che cerca su tutto Hackage per default).
Setup della tua istanza locale di Hoogle
Guardate qui.
Haddock
Fate attenzione, questi post sono lievemente obsoleti: per esempio, adesso Hackage vanta nuovi modi di mostrare informazioni, documentazione e stato del build.
Quello che davvero avete bisogno di sapere
Per far includere ad haddocks la documentazione per i pacchetti correlati, dovete settare documentation: True
nel vostro ~/.cabal/config
. Se lasciato sul valore di default (False
) o settato a False
, prima di rigenerare la documentazione dovrete rimuovere tutti i vostri pacchetti e reinstallarli.
L'altra cosa da tenere a mente è che a causa del modo in cui il parametro $pkg
viene interpretato da cabal, non da voi, i parametri html-location
e content-location
devono essere fra apici e inseriti in una shell o in uno shell script. Non funzioneranno in un Makefile, perché crederanno di essere variabili di Make!
#! /usr/bin/env sh
# potete scrivero su una linea sola non mettendo backslash
cabal haddock --hoogle --hyperlink-source \
--html-location='http://hackage.haskell.org/package/$pkg/docs' \
--contents-location='http://hackage.haskell.org/package/$pkg'
TravisCI
Se siete fan di TravisCI come lo sono io, allora vi consiglio
caldamente di dare un'occhiata a
multi-ghc-travis come base per il travis.yml
dei vostri progetti Haskell.
Frontend/JavaScript
Abbiamo l'imbarazzo della scelta! Ci sono tre scelte principali che raccomanderei:
-
Haste un compilatore da Haskell a JavaScript
- Il compilatore su github.
- Una demo eccellente di Haste con un progetto di esempio.
-
- Non è strettamente Haskell come Haste e GHCJS, ma è una scelta popolare fra i programmatori Haskell
- Scritto in ed ispirato ad Haskell
- Provate purescript nel vostro browser here
- Ottima guida per cominciare a usarlo
Quale linguaggio scegliere per il frontend?
GHCJS e Haste sono entrambi interamente compatibili con Haskell. GHCJS è compatibile con un numero maggiore di pacchetti Haskell rispetto a Haste, ma questo non è rilevante per molti progetti frontend. Al contrario, PureScript non è Haskell, per tanto non potrete condividere il codice fra frontend e backend.
GHCJS ha un runtime più grande, a 100kb (luite ci sta lavorando). Haste e PureScript sono competitivi.
PureScript ha la migliore integrazione con i tool di JS (usa gulp/grunt/bower), mentre GHCJS e Haste si integrano meglio con i tool di Haskell (Cabal).
Tutti e tre sono un'ottima scelta e possono funzionare per la maggioranza dei progetti frontend.
Per una comprensione più profonda della laziness, NF, WHNF
Articoli di ricerca sul lazy lambda calculi
Parallelismo/Concorrenza
-
Il libro Parallel and Concurrent Programming in Haskell di Simon Marlow è probabilmente il migliore che abbia mai letto sull'argomento.
-
Un walk-through completo su testing e incremental development di un applicazione multi-threaded in Haskell.
Lenses e Prisms
Una volta che vi trovate a vostro agio con Haskell, è molto utile imparare Lens e Prism, anche se solo come "utente". Non avete bisogno di capire le categorie sottostanti perchè vi siano utili.
La difficoltà di usare la libreria Lens è generalmente sovrastimata. Chiunque sia a suo agio con Functor/Foldable/Traversable (o anche solo il primo) può usare lens e prism per rendersi la vita più facile.
Se vi è capitato di fare qualcosa come: (fmap . fmap)
stavate usando mentalmente le 'lenti'.
Raccomando questi due tutorial/introduzioni:
Leggete questo per maggiori informazioni: pacchetto Lens su hackage.
Schemi di ricorsione
Alcune delle pazze parole di cui avete sentito parlare che finiscono con *-morfismo riguardano la ricorsione. NB - prima di iniziare a studiare il materiale che segue dovreste sapere come implementare foldr per le liste e almeno un'altra struttura di dati, tipo un albero. (i fold sono catamorfismi) Sapere come implementare un unfold (anamorfismo) per le stesse strutture dati è complementare.
Questo materiale si compenetra con traversable e foldable.
-
Don't fear the cat - Buona dimostrazione su come l'ilomorfismo sia la composizione di cata e ana.
-
Recursion Schemes - Questa guida è ottima.
-
Functional Programming with Bananas, Lenses, Envelopes and Barbed Wire
GHC Core e ottimizzazione della performance
Tipi e Teoria delle Categorie
Non è necessaria per scrivere Haskell, solo per quelli interessati!
Se volete imparare di più su tipi e teoria delle categorie:
-
Il wikibook haskell ha dei bei diagrammi
-
Teoria delle categorie su haskellwiki, ha anche buoni link ad altre risorse
-
Categories from scratch, include alcuni esempi pratici.
-
La lista Great Works in PL di Pierce.
Libri
-
Quora Question: What is the best textbook for category theory? le raccomandazioni di Kmett
-
Awodey e MacLane. I libri di testo standard sulla teoria delle categorie
-
Harper's Practical Foundations for Programming Languages è la miglior introduzione alla teoria delle categorie focalizzata sui linguaggi di programmazione.
Altri argomenti divertenti
Parametricità, ad-hoc vs. polimorfismo parametrico e teoremi liberi
-
Sorgenti TeX per la presentazione di cui sopra.
Inizial e Final, DSL, Finally Tagless
-
The dog that didn't bark meno rilevante nello specifico ma comunque interessante.
Comonadi
Yoneda / CoYoneda
-
Free monads for Less, una sequenza di tre articoli di Edward Kmett
Propositions vs. Judgments (computazione)
Tipi dipendenti
-
Grokking sum types, value constructors, and type constructors strizzate gli occhi.
Linkare binari staticamente
Dialoghi
Disponibile in questo repository qui.
Questi sono in realtà importanti e utili. Leggeteli per approfondimenti su una varietà di argomenti.