learnhaskell/guide-de.md

34 KiB

Die Einführung

Das ist mein empfohlener Weg Haskell zu lernen.

Beachte: Diese Einführung ist zwar in Deutsch, aber alle Referenzen sind leider noch in Englisch.

Denk an folgendes: Mach dir nichts draus, wenn du etwas nicht direkt verstehst. Einfach weiter machen.

Community

Unser IRC channel auf Freenode ist #haskell-beginners.

IRC web client hier.

Die Haskell Mailing Listen.

Community Richtlinien

Siehe Chris Done's Post über Lehre

Sei freundlich und höflich. Unfreundlichkeit und Unhöflichkeit schreckt Leute ab, sodass sie nicht mehr mitmachen wollen.

Wenn du dir keine Mühe bei deiner Kritik gibst, hilft sie der Person, die sie erhält, auch nicht.

Beschreibe Dinge nicht als "einfach" oder "trivial". Leute, die hart für ihren Fortschritt arbeiten müssen, werden sich schlecht fühlen deswegen. Langsame Lerner sind meistens die sorgfältigsten, das sollte gewürdigt werden!

Keine geheuchelte Überraschung. Spiele nicht überrascht, wenn jemand sagt, dass er etwas nicht weiß. Du erreichst nur, dass jemand sicht schlecht fühlt und du dich besonders toll.

Kein "also, eigentlich ...". Wenn jemand etwas sagt, das nahezu richtig ist - aber nicht exakt - und du sagst, "also, eigentlich..." und gibst eine kleine Korrektur. Das ist besonders unnötig, da es keine Nutzen für die eigentlich Konversation hat. Das heißt nicht, dass die Recurse Center nicht an Richtigkeit oder Genauigkeit interessiert ist. Fast alle "also, eigentlich" sind Selbstdarstellung und keine konstruktiven Verbesserungen.

Kein ständiges Reinreden. Wenn du siehst wie jemand ein Problem durcharbeitet, sollest du nicht immer wieder Vorschläge einwerfen. Lass es ihn herausfinden außer er fragt nach Hilfe. Unterbrechungen zu vermeiden ist eine der Gründe für #haskell-beginners.

Rassismus, Sexismus, Homophobie, Transphobie und andere Arten von Vorurteilen sind nicht erwünscht und werden nicht toleriert.


Richtlinien aus the Recurse Center manual. Danke für die Veröffentlichung Recurse Center.

Was sind Haskell, GHC, und Cabal?

Haskell ist eine Programmiersprache, die in einem Report festgelegt wird, der letzte ist von 2010. Der Report ist online verfügbar.

GHC

GHC ist der beliebteste und bekannteste Weg mit Haskell zu arbeiten. Er beinhaltet einen Compiler, REPL (Interpreter), Paket Management, und ein paar weitere Dinge.

Cabal

Cabal ist für Projekt Management und Abhängigkeitsauflösung zuständig. Hiermit installierst du Projekte, normalerweise in ihre eigene Sandbox.

Cabal ist äquivalent zu Rubys Bundler, Pythons pip, Nodes NPM, Maven, etc. GHC kümmert sich selber um die Paketierung, Cabal wählt die zu installierende Version aus.

Installation

Ubuntu

Dieses PPA ist ausgezeichnet und ich benutze es auf allen meine Linux Entwicklungs- und Buildmaschinen.

Genauer:

$ 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

Dann füge das folgende zu deinem $PATH (bash_profile, zshrc, bashrc, etc) hinzu:

~/.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

Optional: Du kannst auch .cabal-sandbox/bin zu deinem PATH hinzufügen. Code, der gerade entwickelt wird, ist dann verfügbar über die Kommandozeile. Das funktioniert aber nur, wenn das aktuelle Verzeichnis eine Cabal Sandbox ist.

Debian

Ubuntu PPA nutzen

Wenn du nicht stable benutzt, kannst du dieselben Schritte wie unter Ubuntu ausführen, aber du musst ein weiteres Kommando ausführen. Direkt nachdem sudo add-apt-repository -y ppa:hvr/ghc ausgeführt wurde, starte:

$ sudo sed -i s/jessie/trusty/g /etc/apt/sources.list.d/hvr-ghc-jessie.list

Für alle anderen Debian Versionen, ersetze einfach alle Vorkommen von jessie mit dem entsprechenden Versionsnamen im Kommando oben.

Wenn, warum auch immer, die Datei /etc/apt/sources.list.d/hvr-ghc-jessie.list nicht existiert, dann sollte /etc/apt/sources.list eine Liste, wie die folgende beinhalten:

deb http://ppa.launchpad.net/hvr/ghc/ubuntu jessie main

Ersetze jessie durch trusty in dieser Zeile.

Manuell Kompilieren

Du kannst dieser Anleitung folgen (geschrieben für Mac OS X):

Anmerkungen:

  • Setze deinen Präfix entsprechend, wenn du GHC konfiguierst
  • Anstatt die cabal-install Binary zu laden, lade die Quellen und führe das Skript bootstrap.sh aus.

Fedora 21

Um Haskell 7.8.4 aus dem unoffiziellen Repo (Fedora 22+ wird es in den offiziellen beinhalten) zu installieren:

$ 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

Wie in auf der Seite petersen/ghc-7.8.4 copr beschrieben kann dieser ghc nicht parallel zu Fedora/EPEL ghc installiert werden.

Arch Linux

Um Haskell aus den offiziellen Repos unter Arch Linux zu installieren, mache folgendes:

$ sudo pacman -S cabal-install ghc happy alex haddock

Gentoo

Unter Gentoo kannst du verschiedene Komponenten der Haskell Platform via Portage installieren. Wenn du ACCEPT_KEYWORDS=arch nutzt (anstatt ACCEPT_KEYWORDS=~arch), installiert Portage die uralt Versionen der verschiedenen Haskell Teile. Daher füge, wenn du, und nur wenn du ACCEPT_KEYWORDS=arch nutzt, das Folgende in /etc/portage/package.keywords ein.

dev-haskell/cabal-install
dev-lang/ghc

Wenn das getan ist:

$ emerge -jav dev-lang/ghc dev-haskell/cabal-install

Gentoo hat eine "stabile" (lies: alte) Version von cabal-install im Portage tree, daher wirst du cabal-install nutzen wollen um eine neuere version zu installieren. Beachte, dass backslashes Absicht sind.

$ \cabal update                # The backslashes
$ \cabal install cabal-install # are intentional

Du hast cabal jetzt global mit Portage und lokal in deinem Home Verzeichnis mit cabal-install installiert. Der nächste Schritt ist sicherzustellen, dass, wenn du cabal im Terminal ausführst, die aktuelle Version genommen wird. Dafür kannst du folgende Zeilen zur Konfiguration deiner Shell hinzufügen:

PATH=$PATH:$HOME/.cabal/bin
alias cabal="$HOME/.cabal/bin/cabal"

Wenn du nicht weißt, was für eine Shell du nutzt, ist es mit hoher Wahrscheinlichkeit die Bash. Wenn du die Bash nutzt, musst du die Datei ~/.bashrc editieren. Wenn du die Z-shell nutzt, ist die Datei ~/.zshrc. Du kannst folgendes Kommando ausführen, um herauszufinden, was für eine Shell du benutzt:

echo $SHELL | xargs basename

Ich nutze zsh, daher ist die Ausgabe zsh, wenn ich es ausführe.

Wenn du all das getan hast, brauchst du die weiteren Toolsalex und happy.

$ cabal install alex happy

Glückwunsch! Du hast jetzt eine funktionierende Haskell installation!

Mac OS X

10.9

Installiere die GHC for Mac OS X App, welche GHC und Cabal beinhaltet. Sie liefert Anweisungen, wie du GHC und Cabal zu deinem path hinzufügen kansnt, nachdem du die .app irgendwo ableget hast.

10.6-10.8

Installiere die Binary Distribution, wie unten beschrieben, mit diesem tarball.

Windows

  • Der minimale ghc Installer für Windows ist in der Lage network und andere zu installieren. Technisch gesehen befindet er sich in der Beta, sollte aber für die Zwecke eines jeden der diese Anleitung ließt funktionieren.

Vergesse nicht den Installer als Administrator auszuführen, da er in deinen Programmen installieren will.

Andere Linux Nutzer

Lade die aktuellen Binary Distributions für cabal und ghc:

Detailierte Installationsanleitung für Mac OS X

Du musst das nicht machen, wenn du die .app nutzt, aber wenn das für dich nicht funktioniert, versuche das mit der Binary Distribution.

Grundlegende Kurse

Yorgey's cis194 Kurs

Den solltest du zuerst machen, das ist eine erstklassige Einführung in Haskell, die ich sehr empfehle

Verfügbar online.

Brent Yorgeys Kurs ist der beste, den ich bisher gefunden habe. Dieser Kurs ist wertvoll, da du nicht nur Grundlegendes über Haskell lernst, sondern auch lernst Parser Combinators zu verstehen.

Der einzige Fall, in dem du nicht mit cis194 anfangen solltest, ist, wenn du kein oder ein unerfahrener Programmierer bist. Wenn das der Fall ist, starte mit Thompsons Buch und gehe über zu cis194.


Data61 Kurs

Das ist der Kurs, den ich nach Yorgeys cis194 Kurs empfehle zu machen

Verfügbar hier auf github

Das wird dein Verständnis verbessern und dir Erfahrung mit der Implementierung der Abstraktionen geben, die in cis194 eingeführt wurden, das ist die Praxis, die ausschlaggebend ist, um mit der üblichen Nutzung von Functor/Applicative/Monad/etc. in Haskell vertraut zu werden. Erst cis194 und dann den Data61 Kurs zu machen, ist die wesentliche Empfehlung meiner Anleitung und ist der Weg, wie ich anderen Leuten Haskell beibringe.


Deutsche Ressourcen

Anmerkung: Dieser Abschnitt wurde bei der Übersetzung eingefügt, um hilfreiche deutsche Inhalte zu verlinken

  • funktionale-programmierung.de ist ein Blog über Funktionale Programmierung im Allgemeinen, welcher auch Posts über Haskell beinhaltet.

  • Skript der Vorlesung Funktionale Programmierung an der RWTH Aachen. Beinhaltet eine kurze Einführung in Haskell, sowie Kapitel über den Lambda Kalkül und Typüberprüfung und -inferenz.


Zusätzliche Kurse cs240h

Stellt weiteres Material für fortgeschrittene Themen bereit

Verfügbar online.

Das ist Bryan O'Sullivans online Version des Kurses, den er in Stanford unterrichtet. Wenn du nicht weißt, wer er ist, guck dir der Hälfte der Libraries an, die jede Haskell Anwendung am Ende braucht und sein Name wird dabei sein. Wenn du bereits den Yorgey Kurs gemacht hast, sind die Module über phantom types, information flow control, language extensions, concurrency, pipes, und lenses von besonderer Bedeutung.


Referenz Material für die drei Kurse

Learn You a Haskell for Great Good (LYAH) und Real World Haskell (Danke bos!) sind online verfügbar.

I empfehle RWH als Referenz (dickes Buch). Die Kapitel über Parsen und Monaden sind sehr gut, um ein Verständnis dafür zu kriegen, wofür Monaden nützlich sind. Andere Leute sagen, dass sie es oft verlinkt haben. Vermutlich eine gute Nachbereitung für die praktischen Teile nachdem du die essentiellen Sachen in Haskell verstanden hast?

Was macht dieser <- / do / list comprehension syntaktische Zucker?

Exzellenter Artikel.

Um Listen und Fold zu verstehen

Um ein paar wesentliche Typ Klassen zu lernen

Nützlich um Functor, Applicative, Monad, Monoid und andere Typ Klassen im Allgemeinen zu verstehen aber auch etwas Hask-bezogene Kategorien Theorie:

Die grundlegenden Haskell Fehler Meldungen verstehen


Laziness, strictness, guarded recursion

Kurze Demonstration

let a = 1 : a -- guarded recursion, (:) is lazy and can be pattern matched.
let (v : _) = a
> v
1
> head a -- head a == v
1

let a = 1 * a -- not guarded, (*) is strict
> a
*** Exception: <<loop>>

IO

Kommentar auf Reddit von glaebhoerl

Übersetzt:

Interessante Randbemerkung: GHC muss die state token Darstellung hinter einem abstrakten IO Typ verstecken, weil der state token immer linear benutzt werden muss (nicht dupliziert oder dropped(??)), aber das Typsystem kann das nicht erzwingen. Clean, ein andere lazy Haskell-ähnliche Sprache, hat eindeutige Typen (die ähnliche zu Linearen Typen sind und vermutlich anders in vielen Aspekten, die mir nicht bekannt sind), und sie stellen World-passing(??) direkt und eine (nicht abstrakte) IO Monade nur der Einfachheit halber bereit.

Original:

Interesting side note: GHC needs to hide the state token representation behind an abstract IO type because the state token must always be used linearly (not duplicated or dropped), but the type system can't enforce this. Clean, another lazy Haskell-like language, has uniqueness types (which are like linear types and possibly different in ways I'm not aware of), and they expose the World-passing directly and provide a (non-abstract) IO monad only for convenience.

Monaden und Monaden Transformer (monad transformers)

Versuche nicht diese zu lernen bis du nicht Typ Klassen, Monoide, Funktoren und Applikativen verstanden hast

Implementiere die Monaden aus der Standard Bibliothek ( List, Maybe, Cont, Error, Reader, Writer, State ) für dich selbst, um sie besser zu verstehen. Dann schreibe vielleicht einen monadischen Interpreter für eine kleine Expression Sprache mit dem Monad Transformers Step by Step Paper (erwähnt in 'monad transformers' im folgenden).

Mehrere Interpreter zu schreiben, indem man einfach nur die Monade ändert um die Semantik zu verändern kann helfen, zu verstehen was passiert.

Zusätzlich, implementiere Control.Monad selbst. Funktionen wie mapM oder sequence sind gute Möglichkeiten, um zu üben, generischen monadischen Code zu schreiben.

Der Data61 Kurs kann als Anleitung für diese Prozess genutzt werden, was auch beinhaltet eine eigene Applicative zu schreiben.

Credits:

  • Reddit Kommentar von htmltyp und Crandom hier.

  • Reddit Kommentar von jozefg hier.

Monad transformers

Testen, Tests, Specs, generative/property testing

  • Dieses Tutorial von Kazu Yamamoto ist fantastisch.

  • Simple-Conduit: Gute, einfache Bibliothek um zu lernen, wie streaming IO funktioniert im Allgemeinen, die Konzepte sind transferierbar auf Bibliotheken wie Pipes und Conduit

Parsen in Haskell

Parsen und generieren von JSON

Aeson ist die standard Lösung für parsen von JSON in Haskell. Verfübar über hackage und github.

Graph Algorithmen und Datenstrukturen

Entwicklungsumgebung

Emacs

Vim

Sublime Text

Arbeiten mit Cabal

Cabal Leitfaden

Cabal Hell war ein Problem für Haskell Nutzer vor der Einführung von Sandboxes. Eine Installation außerhalb einer sandbox wird in die user package-db installieren. Das ist keine gute Idee außer für grundlegende Pakete wie Cabal, alex, und happy. Nichts anderes sollte in den user oder der globalen package-db installiert sein, außer du weißt was du tust

Hier gibt es ein paar gute Praktiken um Cabal hell zu verhindern.

Um mit einem Paket zu experimentieren oder ein Projekt zu starten, beginne mit cabal sandbox init in einem neuen Verzeichnis.

Kurz gesagt:

  • Nutze immer Sandboxes, um neue Pakete zu installieren, neue oder existierende Projekte zu bauen oder Experimente zu starten

  • Nutze cabal repl um eine Projekt bezogene ghci Instanz zu starten

Die vorgeschlagene, sandbox-basierte Methode sollte Paket Abhängigkeits Probleme vermeiden aber sie ist inkompatibel zu der Art wie die Haskell Plattform fertig gebaute Pakete bereitstellt. Wenn du momentan noch Haskell lernst und nicht verstehst wie ghc-pkg und Cabal funktionieren, nutze nicht die Plattform und stattdessen die Instruktionen, die zu Beginn erklärt wurden.

Stackage

Für alle Nutzer (normalerweise Yesod Nutzer), die Build Probleme haben, zieht Stackage in Erwägung:

  • Eine gute Zusammenfassung ist hier.

Der Meinung des Authors nach, ist Stackage normalerweise nützlicher als ein cabal freeze.

Hoogle und Haddock

Suche Code nach der Typ Signatur

Die Hoogle Suchmaschine kann nach Typen suchen.

Zum Beispiel, guck dir die such Resultate für (a -> b) -> [a] -> [b] an.

Auch verfügbar über FPComplete hier.

Außerdem gibt es Hayoo (welches standardmäßig ganz hackage durchsucht).

Eine eigene lokale Instanz von Hoogle aufsetzen

Siehe hier.

Haddock

  1. Fix your hackage documentation

  2. Hackage Dokumentation v2

Beachte, dass diese Artikel etwas veraltet sind: Zum Beispiel hat Hackage jetzt eine neue Info mit Dokumentations- und Build-Status.

Was du wirklich wissen solltest

Damit Haddock Dokumentation für verwandte Pakete inkludiert, musst du documentation: True in deiner ~/.cabal/config setzen. Wenn es auf Standard Wert (False) gelassen wurde, musst du alle Pakete löschen und neu installieren bevor die Haddocks generiert werden.

Die andere Sache, an die man denken sollte, ist, dass aufgrund der Art wie $pkg interpoliert wird von cabal, nicht von dir, die html-location und content-location Parameter in Apostrophen stehen müssen und in die Shell eingegeben werden oder in einem Shell Skript stehen. Sie werden nicht in einer Makefile funktionieren, da Make denken wird es seien Make Variablen.

#! /usr/bin/env sh

# You can write it one one line by skipping the backslashes
cabal haddock --hoogle --hyperlink-source                       \
 --html-location='http://hackage.haskell.org/package/$pkg/docs' \
 --contents-location='http://hackage.haskell.org/package/$pkg'

TravisCI

Wenn du, wie ich, ein großer Fan von TravisCI bist, dann empfehle ich sehr multi-ghc-travis anzugucken für die Basis der travis.yml für deine Haskell Projekte.

Frontend/JavaScript

Wir haben eine große Auswahl! Im Grunde gibt es drei Möglichkeiten, die ich empfehlen würde:

Welche Frontend Sprache nutze ich?

GHCJS und Haste sind beide komplett Haskell. GHCJS wird mit mehr Haskell Paketen funktionieren als Haste, aber ist egal für viele Frontend Projekte. Purescript ist kein Haskell, daher ist es nicht möglich Code direkt mit dem Backend zu teilen.

GHCJS hat den größten Laufzeit Overhead mit über 100kb (luite arbeitet daran). Haste und Purescript sind vergleichbar.

PureScript hat die beste JS Tooling Integration (nutzt gulp/grunt/bower), GHCJS und Haste integrieren besser mit Haskells Tooling (Cabal).

Alle drei sind eine gute Wahl und werden für die meisten Frontend Projekte genügen.

Für ein tiefergehendes Verständnis für Laziness, NF, WHNF

Forschungs Paper über Lazy Lambda Calculi

Parallelisierung/Nebenläufigkeit

Lenses und Prisms

Nachdem du vertraut bist mit Haskell, solltest du unbedingt in Betracht ziehen Lenses und Prims zu lernen, auch wenn du nur ein "Nutzer" bist. Du brauchst nicht du zu grunde liegende Kategorie zu verstehen damit es nützlich ist.

Die Schwierigkeit Lens zu nutzen wird oft stark überschätzt. Jeder der vertraut ist mit Functor/Foldable/Traversable (oder nur dem ersten der drei) kann Lenses und Prisms bereits nutzen, um sein Leben leichter zu machen.

Wenn du jemals etwas wie (fmap . fmap) gemacht hast, hast du bereits in deinem Kopf "lensing" gemacht.

Ich empfehle zwei dieser Tutorials/Einführungen:

Siehe hier für weitere Informationen: Lens Paket auf Hackage.

Recursion Schemes

Einige der verrückten *-morphismus wörter, die du gehört hast, sind eigentlich über Rekursion. Beachte - Bevor du diese Material betrachtest, solltest du wissen, wie man foldr für Listen implementiert und mindestens eine andere Datenstruktur, wie z.B. einen Baum (folds sind Catamorphismen). Wenn du auch noch weißt, wie man ein unfold (Anamorphismus) implementiert, ist das hilfreich.

Diese Material passt gut mit Traversable und Foldable zusammen.

GHC Core und Performance Verbesserungen

Typ und Kategorien Theorie

Nicht notwending um in Haskell zu entwickeln, nur für Interessierte!

Wenn du dich mit Typ- oder Kategorien Theorie beschäftigen willst:

Bücher

Andere interessante Themen

Parametricity, ad-hoc vs. parametric polymorphism, free theorems

Initial und Final, DSLs, Finally Tagless

Comonads

Yoneda / CoYoneda

Propositions vs. Judgments (computation)

Dependent typing

Statisch gelinkte Binaries

Dialog

In diesem Repository zu finden, siehe hier.

Die sind eigentlich sehr wichtig und hilfreich. Schaue hier für tiefere Einblicke in eine Vielzahl von Themen.