learnhaskell/guide-it.md
Chris Allen 268f5a9a19 cleanup
2015-05-07 14:52:14 -05:00

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 script bootstrap.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

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

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.

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:

  • Commenti su Reddit di htmltyp and Crandom qui.

  • Commenti su Reddit di jozefg qui.

Monad transformers

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

Parsare e generare JSON

Aeson è la soluzione di parsing JSON standard in haskell. Disponibile su hackage e github.

Algoritmi per grafi e strutture dati

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

  1. Aggiusta la tua documentazione hackage

  2. Documentazione Hackage v2

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:

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

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.

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:

Libri

Altri argomenti divertenti

Parametricità, ad-hoc vs. polimorfismo parametrico e teoremi liberi

Inizial e Final, DSL, Finally Tagless

Comonadi

Yoneda / CoYoneda

Propositions vs. Judgments (computazione)

Tipi dipendenti

Linkare binari staticamente

Dialoghi

Disponibile in questo repository qui.

Questi sono in realtà importanti e utili. Leggeteli per approfondimenti su una varietà di argomenti.