Haskell (Programmiersprache)

Werbung
10.12.12
Haskell (Programmiersprache) – Wikipedia
Haskell (Programmiersprache)
aus Wikipedia, der freien Enzyklopädie
Haskell ist eine rein funktionale
Programmiersprache, benannt nach dem USamerikanischen Mathematiker Haskell Brooks
Curry, dessen Arbeiten zur mathematischen Logik
eine Grundlage funktionaler Programmiersprachen
bilden. Haskell basiert auf dem Lambda-Kalkül,
weshalb auch der griechische Buchstabe Lambda
als Logo verwendet wird. Die wichtigsten
Implementierungen sind der Glasgow Haskell
Compiler (GHC) und Hugs, ein
Haskell-Interpreter.
Inhaltsverzeichnis
1 Entwicklung
2 Eigenschaften
3
4
5
6
7
8
9
2.1 Programmfluss
2.2 Typsystem
2.3 Syntax
2.4 Programmierung
2.5 Module
Beispiele
3.1 Fakultät
3.2 Fibonacci
3.3 Differenzengleichung
3.4 Quicksort
3.5 Algebra
Implementierungen
Einfluss
Siehe auch
Literatur
Weblinks
Einzelnachweise
Haskell
Basisdaten
Paradigmen:
funktional, nicht-strikt, modular,
deklarativ
Erscheinungsjahr:
1990
Entwickler:
Simon Peyton Jones , Paul Hudak, [1]
Philip Wadler, et al.
Aktuelle Version:
Haskell 2010 (November 2009[2])
Typisierung:
statisch, stark, Typinferenz
GHC (http://www.haskell.org/ghc/) ,
Wichtige
Implementierungen: Hugs (http://www.haskell.org/hugs/) ,
NHC
(http://www.cs.york.ac.uk/fp/nhc98/)
, JHC
(http://repetae.net/john/computer/jhc/)
, Yhc
Dialekte:
Helium, Gofer
Beeinflusst von:
APL, LISP, Miranda, ML
Beeinflusste:
Agda, Cayenne, Clean, Curry, Python,
Scala
haskell.org (http://www.haskell.org/)
Entwicklung
Gegen Ende der 1980er Jahre gab es bereits einige funktionale Programmiersprachen. Um der Wissenschaft
eine einheitliche Forschungs- und Entwicklungsbasis bereitzustellen, sollte eine standardisierte und moderne
Sprache die funktionale Programmierung vereinheitlichen. Zunächst wollte man dazu Miranda als Ausgangspunkt
benutzen; doch deren Entwickler waren daran nicht interessiert. So wurde 1990 Haskell 1.0 veröffentlicht.
de.wikipedia.org/wiki/Haskell_(Programmiersprache)
1/12
10.12.12
Haskell (Programmiersprache) – Wikipedia
Die aktuelle Version der Programmiersprache ist eine überarbeitete Variante des Haskell-98-Standards von
1999. Haskell ist die funktionale Sprache, an der zurzeit am meisten geforscht wird. Demzufolge sind die
Sprachderivate zahlreich; dazu zählen Parallel Haskell, Distributed Haskell (ehemals Goffin), Eager Haskell,
Eden mit einem neuen Ansatz zum parallelen Programmieren und Bedarfsauswertung, DNA-Haskell und sogar
objektorientierte Varianten (Haskell++, O'Haskell, Mondrian). Des Weiteren diente Haskell beim Entwurf
neuer Programmiersprachen als Vorlage. So wurde beispielsweise im Falle von Python die Lambda-Notation
sowie Listenverarbeitungssyntax übernommen.
Eigenschaften
Programmfluss
Haskell ist eine rein funktionale Programmiersprache. Funktionen geben nur Werte zurück, ändern aber
nicht den Zustand eines Programms (d. h. Funktionen haben keine Nebeneffekte). Das Ergebnis einer
Funktion hängt deshalb nur von den Eingangsparametern ab, und nicht davon, wann oder wie oft die
Funktion aufgerufen wird. (siehe funktionale Programmierung)
Es gibt keine imperativen Sprachkonstrukte. Durch Monaden ist es möglich, Ein- und
Ausgabeoperationen und zustandsabhängige Berechnungen wie Zufallsgeneratoren rein funktional zu
behandeln.
Es gibt keine Operationen, die einen Variablenwert verändern. So gibt es auch keine Unterscheidung
zwischen Variablen und Konstanten und man braucht keine const-Attribute oder Literal-Makros wie in
C++ oder in C.
Zwischen Identität und Gleichwertigkeit von Objekten wird nicht unterschieden.
Da Nebeneffekte fehlen, sind Programmbeweise beträchtlich einfacher.
Haskell ist nicht-strikt. Es werden nur Ausdrücke ausgewertet, die für die Berechnung des Ergebnisses
gebraucht werden.
first x y = x
quadrat x = x * x
Die Funktion firstliefert bei Eingabe zweier Parameter den ersten als Ergebnis zurück. Bei der Eingabe
von first x (3+7)ist die Auswertung der Summe (3+7)zur Ergebnisbestimmung nicht notwendig,
sollte also unberücksichtigt bleiben.
Die Funktion quadratberechnet bei Eingabe eines Parameters dessen Quadrat. Bei Eingabe von
quadrat(3+5), was im Laufe des Auswertungsprozesses zu (3+5)*(3+5)wird, wäre eine doppelte
Berechnung der Summe (3+5)ineffizient, sollte also vermieden werden.
Die Auswertungsstrategie, welche die beiden eben geschilderten Probleme umgeht, wird
Bedarfsauswertung (engl. lazy evaluation) genannt und kommt in Haskell meist zum Einsatz.
Die Bedarfsauswertung ist vor allem wegen der strengen Einhaltung des funktionalen Konzepts möglich.
Umgekehrt macht die Bedarfsauswertung die funktionale Programmierung angenehmer, denn sie erlaubt
es besser, Funktionen, die reine Berechnungen durchführen, von Ein-/Ausgabefunktionen zu trennen.
de.wikipedia.org/wiki/Haskell_(Programmiersprache)
2/12
10.12.12
Haskell (Programmiersprache) – Wikipedia
Die Bedarfsauswertung erlaubt das Arbeiten mit undefinierten Werten und potentiell unendlich großen
Datenmengen. So kann man elegant mit Potenzreihen, Zeitreihen (etwa Audiosignalströmen),
Kettenbruchzerlegungen, Entscheidungsbäumen und ähnlichem umgehen. Aber auch bei endlichen, aber
großen, oder endlichen und noch nicht vollständig bekannten Daten erlaubt diese Art der Ausführung
elegante Programme. So kann man etwa eine Transformation eines XML-Dokumentes als Folge von
Transformationen des gesamten XML-Baumes beschreiben. Ausgeführt wird die Gesamttransformation
aber von Beginn zum Ende des XML-Dokumentes, auch wenn das Ende noch gar nicht verfügbar ist.
Man beachte allerdings, dass Haskell nach Sprachdefinition lediglich nicht-strikt ist; die
Bedarfsauswertung ist nur eine mögliche Implementierung der Nicht-Striktheit (die allerdings von allen
gängigen Haskell-Übersetzern angewandt wird). Andere Implementierungen sind möglich (z. B.
optimistic evaluation, Ennals & Peyton Jones, ICFP'03).
Typsystem
Haskell ist stark typisiert. Es wird also zum Beispiel streng zwischen Wahrheitswerten, Zeichen, ganzen
Zahlen, Gleitkommazahlen und Funktionen von und zu verschiedenen Typen unterschieden.
Haskell erlaubt Typvariablen. Damit können Funktionen sehr allgemein formuliert werden. Wird eine
allgemeingehaltene Funktion für bestimmte Typen verwendet, werden automatisch die Typen abgeglichen
(Typinferenz).
Die Funktion mapwendet eine beliebige Funktion auf die Elemente einer Liste an. Ihr Typ wird so
angegeben:
map :: (a -> b) -> [a] -> [b]
Wird mapetwa mit der speziellen Funktion toUppervom Typ Char -> Charaufgerufen, ergibt der
Typabgleich
map toUpper :: [Char] -> [Char]
Haskell ist von der Grundidee her statisch typisiert, obwohl es auch Erweiterungen für dynamische Typen
gibt. Das bedeutet, dass für die meisten Berechnungen die Typen bereits zum Zeitpunkt der
Programmübersetzung feststehen. Dies deckt viele „offensichtliche“ Fehler noch vor Ausführung des
Programms auf.
Haskell unterstützt Funktionen höherer Ordnung (Funktionale). Das sind Funktionen, die Funktionen als
Eingabeparameter bzw. Funktionen als Ergebnis haben. Ein Beispiel ist die map-Funktion, die eine
Funktion fauf jedes Element eines Datentypes (hier Liste) anwendet.
map :: (a -> b) -> [a] -> [b]
map f [] = []
map f (x:xs) = f x : map f xs
map quadrat [1,2,3] = [quadrat 1, quadrat 2, quadrat 3] = [1,4,9]
Funktionen erlauben Currying. Während man in anderen Sprachen Tupel als Argumente an Funktionen
übergibt, also Funktionstypen der Form (a, b) -> cverwendet, ist in Haskell die Curry-Form a
-> b -> cüblicher. Damit wird die partielle Auswertung von Funktionen bequem möglich. Der
Ausdruck
ist beispielsweise eine teilweise Auswertung von map, denn er beschreibt eine3/12
map toUpper
de.wikipedia.org/wiki/Haskell_(Programmiersprache)
10.12.12
Haskell (Programmiersprache) – Wikipedia
Ausdruck map toUpperist beispielsweise eine teilweise Auswertung von map, denn er beschreibt eine
Funktion, nämlich die Funktion, welche alle Kleinbuchstaben einer Liste in Großbuchstaben verwandelt.
Haskell erlaubt benutzerdefinierte Datentypen. Diese algebraischen Datentypen werden mit Hilfe von
Datenkonstruktoren definiert.
data Tree = Leaf Int | Branch Int Tree Tree
Das Beispiel zeigt die Datenstruktur eines mit ganzen Zahlen beschrifteten binären Baumes. Solch ein
Baum Treebesteht entweder aus einem Blatt (Leaf Int) oder einer Verzweigung (Branch Int
t1 t2), wobei t1und t2die Teilbäume darstellen, die wiederum die Struktur Treehaben. Zur
Definition dieser Datenstruktur wurde sowohl der einstellige Konstruktor Leafals auch der dreistellige
Konstruktor Branchverwendet.
Datentypen mit mehreren ausschließlich parameterlosen Konstruktoren können als Aufzählungen
eingesetzt werden.
data Tag = Montag | Dienstag | Mittwoch | Donnerstag | Freitag | Samstag | Sonntag
deriving (Show, Eq, Ord, Ix, Enum)
Haskell unterstützt Typenklassen. Mit Typenklassen lassen sich Typen zusammenfassen, welche eine
bestimmte Menge an Operationen unterstützen. In Signaturen von Funktionen dürfen als Abstufung
zwischen festen Typen wie Charund freien Typvariablen auch noch Typvariablen mit Einschränkung auf
bestimmte Klassen verwendet werden.
Alle Ausprägungen einer Methode der Typklasse tragen den gleichen Namen. In gewisser Weise
entsprechen Typklassen also dem Überladen von Funktionen. Der gleiche Funktionsname steht also
abhängig vom Typ für verschiedene Funktionen. Zum Beispiel ist mit der ==-Methode der Klasse Eqder
Vergleich sowohl zweier Zahlen als auch zweier Texte möglich. Trotzdem arbeitet der Gleichheitstest je
nach Argumenttyp anders.
In Haskell haben Ein- und Ausgabefunktionen einen speziellen Typkonstruktor namens IO.
putStrLn :: String -> IO ()
getLine :: IO String
putStrLngibt einen Text und
einen Zeilenumbruch auf der Standardausgabe aus. Da es kein
informationstragendes Ergebnis gibt, wird der Einheitstyp ()als Rückgabetyp verwendet. getLineliest
eine Textzeile von der Standardeingabe. Der IO-Typkonstruktor stellt sicher, dass man den Nutzern der
Funktion offenlegen muss, dass die Ergebnisse durch Ein-/Ausgabe gewonnen wurden. Diese strenge
Handhabung ermuntert Haskell-Programmierer zur klaren Trennung von Ein- und Ausgabe und anderen
Teilen eines Programms. Der größte Teil eines Haskell-Programms besteht in der Regel aus Funktionen
ohne Ein- und Ausgabe. Man kann IO-Typen natürlich auch in andere Typen einbetten und so zum
Beispiel einen speziellen IO-Typ definieren, der nur Eingaben erlaubt.
Syntax
Haskell unterscheidet Groß- und Kleinschreibung. Bezeichner, die mit einem Großbuchstaben beginnen, stehen
für Typ- und Wertkonstruktoren. Bezeichner, die mit einem Kleinbuchstaben beginnen, stehen für Typvariablen,
de.wikipedia.org/wiki/Haskell_(Programmiersprache)
4/12
10.12.12
Haskell (Programmiersprache) – Wikipedia
Funktionen und Parameter.
Der Umgang mit Leerzeichen und Zeilenumbrüchen geschieht in Anlehnung an das intuitive Verständnis von
mathematischer Notation, bei Zeilenumbrüchen muss lediglich eine Einrückung beliebiger Tiefe geschehen, damit
der Zusammenhang nicht verloren geht. So ist der Ausdruck
fun a b = a*b
völlig gleichwertig zu
fun a b= a *
b
Haskell unterstützt einzeilige und mehrzeilige Kommentare, erstere ab den Zeichen --bis zum Ende der Zeile
und letztere im Einschluss von {-und -}.
f x = x**2
-- f y = y*5 diese Zeile ist auskommentiert
{- Alles, was
hier drin steht, wird auch nicht beachtet.
f z = z*2
-}
Haskell bietet eine Reihe von syntaktischen Besonderheiten. Diese sollen nicht darüber hinwegtäuschen, dass
alles rein funktional erklärt ist.
Die do-Notation verleiht Berechnungen mit Monaden das Aussehen von imperativen Programmen.
Statt
readFile "eingabe.txt" >>= writeFile "ausgabe.txt"
oder
readFile "eingabe.txt" >>= (\inhalt -> writeFile "ausgabe.txt" inhalt)
kann man auch
do inhalt <- readFile "eingabe.txt"
writeFile "ausgabe.txt" inhalt
schreiben.
Sowohl symbolische Bezeichner (bestehend etwa aus +, -, *, /, >, <) als auch alphanumerische
Bezeichner (Buchstaben, Ziffern und Apostroph) können für Funktionen verwendet werden und sowohl
als Infix-Operatoren als auch in Präfixschreibweise eingesetzt werden. Es gilt beispielsweise
a+b
= (+) a b
a `div` b = div a b
Haskell erlaubt eine Notation für die Listenverarbeitung (list comprehensions). So können Zahlenfolgen
mit zwei Punkten (..) angedeutet werden:
de.wikipedia.org/wiki/Haskell_(Programmiersprache)
5/12
mit zwei Punkten (..) angedeutet werden:
[0..5] = [0,1,2,3,4,5]
['a'..'e'] = ['a','b','c','d','e'] = "abcde"
[0,2..10] = [0,2,4,6,8,10]
Wird kein Endwert angegeben, dann wird eine unendliche Liste erzeugt
[1..] = [1,2,3, usw.]
[10,20..] = [10,20,30, usw.]
Des Weiteren ist eine Notation erlaubt, die an die mathematische Schreibweise für Mengendefinitionen
angelehnt ist. In folgendem Beispiel wird aus der Folge der positiven natürlichen Zahlen die Folge der
geraden Zahlen extrahiert.
[ x | x <- [1..], even x]
als Umschreibung für
filter even [1..]
bzw. für
do
x <- [1..]
guard $ even x
return x
Im Allgemeinen kann hinter dem senkrechten Strich eine beliebige nichtleere Folge aus Generatoren (pat
<- xs), Prädikaten (Ausdrücken mit dem Typ Bool) und let-Bindungen angegeben werden.
Insbesondere ist es möglich, überhaupt keine Generatoren zu verwenden. Der Ausdruck
[x | odd x]
nimmt je nach Wert von x, welches als bereits definiert vorausgesetzt wird, den Wert []oder [x]an.
Programmierung
Haskell erlaubt Mustervergleiche (engl. „pattern matching“). So nennt man die Verwendung von
Konstruktortermen als formale Parameter. Dabei sind die Parameterterme die Muster (engl. „pattern“)
der Funktionsargumente.
fak :: Integer -> Integer
fak 0 = 1
fak n = n * fak (n-1)
Die Funktion fakberechnet die Fakultät einer Zahl. 0und nsind dabei die Muster (Pattern), von denen
die Ergebnisbestimmung abhängt. Für Zahlen größer als 0 greift nur das Muster n, so dass zweitere
Alternative verwendet wird. Diese errechnet das Ergebnis durch n * fak (n-1), wobei sie sich, so
10.12.12
Haskell (Programmiersprache) – Wikipedia
lange (n-1) > 0rekursiv selbst aufruft, bis sie bei 0ankommt. Dort greift dann das Muster 0, so
dass erstere Alternative verwendet wird, welches die Rekursion sauber abschießt, 1zurückgibt, und die
Rücksprungkette einleitet.
Module
Zu Haskell gehört auch ein Modulsystem. Der Haskell-98-Standard definiert eine Grundmenge von Modulen,[3]
die ein standardkonformes Haskell-System zur Verfügung stellen muss. Beispielsweise ein Modul, welches Einund Ausgabe-Funktionen bereitstellt oder ein Modul, welches Funktionen auf Listen implementiert.
Um Module nutzen zu können, muss man sie importieren. Dies geschieht mithilfe des importBefehls.
import List
import Maybe
In verschiedenen Modulen können Funktionen und Typen die gleichen Namen besitzen. Diese Bezeichner
können unterschieden werden,
indem nur einer der Bezeichner importiert wird,
import Data.List(delete)
x = delete 'a' "abc"
oder indem die Bezeichner qualifiziert, also durch Verbinden mit dem Modulnamen eindeutig gemacht
werden.
import qualified Data.List
x = Data.List.delete 'a' "abc"
oder
import qualified Data.List as List
x = List.delete 'a' "abc"
Ebenfalls möglich aber nicht empfohlen ist das Ausblenden von Bezeichnern beim Importieren mit hiding.
Beispiele
Fakultät
Eine elegante Definition der Fakultätsfunktion, die Haskells Notation für Listen benutzt:
fac :: Integer -> Integer
fac n = product [1..n]
Fibonacci
Eine einfache Implementierung der Fibonacci-Funktion:
7/12
10.12.12
Haskell (Programmiersprache) – Wikipedia
fib :: Integer -> Integer
fib 0 = 0
fib 1 = 1
fib n = fib (n - 2) + fib (n - 1)
Eine schnelle Implementierung der Folge:
fibs :: [Integer]
fibs = 0 : 1 : (zipWith (+) fibs (tail fibs))
tailentfernt das erste Element aus einer Liste, zipWithkombiniert zwei Listen elementweise mithilfe einer
weiteren Funktion (hier (+)). Die Definition entspricht einer Fixpunktgleichung. Dass die Definition stimmt,
überprüft man am schnellsten, indem man sich vorstellt, dass fibsbereits fertig berechnet vorliegt. Als nächstes
muss man sich noch überlegen, dass die Definition auch ausgewertet werden kann. Die ersten beiden Glieder
von fibssind unmittelbar klar: 0 und 1. Für das Berechnen jedes weiteren Gliedes muss aber nur auf bereits
berechnete Glieder von fibszurückgegriffen werden. Die Bedarfsauswertung führt dazu, dass die Folge fibs
tatsächlich elementweise berechnet wird.
Man könnte auch sagen, dass fibsein Fixpunkt der Funktion \xs -> 0 : 1 : (zipWith (+)
xs (tail xs)) ist. Das wiederum lässt sich in Haskell direkt notieren als
fix (\xs -> 0 : 1 : (zipWith (+) xs (tail xs)))
Differenzengleichung
Man kann auf diese Weise sehr elegant Differentialgleichungen bezüglich Potenzreihen oder
Differenzengleichungen bezüglich Zahlenfolgen formulieren und gleichzeitig lösen.
Angenommen, man möchte die Differentialgleichung y'(x) = f(x, y(x)) bezüglich y in Form einer Zeitreihe
lösen, also einer Liste von Zahlen. Durch diese Diskretisierung wird die Differentialgleichung zur
Differenzengleichung. Statt eines Integrals berechnen wir Partialsummen. Die folgende Funktion hat als
Parameter die Integrationskonstante und eine Zahlenfolge.
integrate :: Num a => a -> [a] -> [a]
integrate = scanl (+)
scanlakkumuliert die Werte einer Folge mit Hilfe einer anderen Funktion,
hier (+), und gibt die Liste der
Akkumulatorzustände zurück.
Damit kann man bereits das explizite Eulerverfahren für die Schrittweite 1 implementieren. x0und y0sind
hierbei die Anfangswerte. Der Apostroph hat keine eigenständige Bedeutung, er ist Teil des Namens y'.
eulerExplicit :: Num a => (a -> a -> a) -> a -> a -> [a]
eulerExplicit f x0 y0 =
let x = iterate (1+) x0
y = integrate y0 y'
y' = zipWith f x y
in y
Diese Funktionsdefinition besteht also im Wesentlichen aus der Feststellung, dass ydas Integral von y'mit
Anfangswert y0ist, (oder umgekehrt, y'die Ableitung von y) und aus der eigentlichen Differentialgleichung
de.wikipedia.org/wiki/Haskell_(Programmiersprache)
8/12
y' = zipWith f x y. Weil man hierbei den Algorithmus eher in der Form der Aufgabenstellung als in
Form eines Lösungsweges notiert, spricht man hierbei von deklarativer Programmierung.
Quicksort
Der Quicksort-Algorithmus, formuliert in Haskell:
qsort :: Ord a => [a] -> [a]
qsort []
= []
qsort (x:xs) = qsort kleinergl ++ [x] ++ qsort groesser
where
kleinergl = [y | y <- xs, y <= x]
groesser = [y | y <- xs, y > x]
Die erste Zeile definiert die Signatur von Quicksort. Die zweite Zeile gibt an, dass die Funktion auf eine leere
Liste angewendet wieder eine leere Liste ergeben soll. Die dritte Zeile sortiert rekursiv nicht-leere Listen: das
erste Element xwird als mittleres Element der Ergebnisliste verwendet. Davor werden alle nicht-größeren
sortiert, dahinter alle größeren Elemente eingeordnet. Listenbeschreibungen werden dazu verwendet, aus der
Restliste xsalle diejenigen auszuwählen, die größer als xsind, und alle jene, die es nicht sind.
Wie man es von Quicksort erwartet, besitzt auch diese Implementierung eine mittlere asymptotische Laufzeit von
O(n·logn) und eine Worst-Case-Laufzeit von O(n²). Im Gegensatz zur geläufigen Implementierung in einer
imperativen Sprache arbeitet dieses qsortjedoch nicht in-place.
Algebra
Dieses Beispiel stellt die Nutzung von Typklassen heraus.
data PhiNum a = PhiNum { numPart :: a, phiPart :: a } deriving (Eq, Show)
instance Num a => Num (PhiNum a) where
fromInteger n = PhiNum (fromInteger n) 0
PhiNum a b + PhiNum c d = PhiNum (a+c) (b+d)
PhiNum a b * PhiNum c d = PhiNum (a*c+b*d) (a*d+b*c+b*d)
negate (PhiNum a b) = PhiNum (-a) (-b)
abs = undefined
signum = undefined
fib n = phiPart $ PhiNum 0 1 ^ n
fibstellt eine schnelle Berechnung von Elementen der Fibonacci-Folge dar.
Ausgenutzt wird das vordefinierte
^, das auf Num-implementierenden Typen arbeitet.
Implementierungen
Es gibt inzwischen eine Reihe Haskell-Implementierungen, von denen die meisten aber den Sprachstandard nicht
vollständig umsetzen.
Der Glasgow Haskell Compiler[4] (GHC) unterstützt Haskell 98 sowie zahlreiche Spracherweiterungen.
Er übersetzt Haskell-Programme in Maschinencode; für nicht direkt unterstützte Plattformen erzeugt er
C-Code, der dann mit einem C-Compiler übersetzt wird.
Hugs[5] ist ein Bytecode-Compiler, der Haskell 98 fast vollständig sowie einige Erweiterungen
implementiert. Hugs ist selbst in C geschrieben.
nhc[6] [7] (auch nhc98) ist ein weiterer Bytecode-Compiler, der Haskell 98 mit gewissen
10.12.12
Haskell (Programmiersprache) – Wikipedia
Einschränkungen unterstützt. Der York Haskell Compiler oder Yhc ist eine Weiterentwicklung von nhc
mit dem Ziel, Portabilität und Performance der kompilierten Programme zu verbessern.
Der Utrecht Haskell Compiler[8] (UHC) ist eine experimentelle Implementierung, die an der Universität
Utrecht entwickelt wird. Der Compiler basiert auf Attributgrammatiken und übersetzt Haskell in C-Code.
Er implementiert Haskell 98 fast vollständig sowie einige Erweiterungen.
Helium[9] wird ebenfalls an der Universität Utrecht entwickelt. Der Schwerpunkt des Projekts liegt
darauf, leicht verständliche Fehlermeldungen zu erzeugen, um Anfängern das Erlernen von Haskell zu
erleichtern. Daher wird auch ein eingeschränkter Haskell-Dialekt implementiert, der unter anderem keine
Typklassen hat.
Die hier genannten Implementierungen sind alle Open-Source-Software. Bis auf Hugs sind sie auch alle in
Haskell selbst implementiert.
Einfluss
Haskell diente und dient wegen seiner stark akademischen Herkunft vielen Programmier- und Scriptsprachen als
Vorbild für neue Sprachfunktionalität. So haben u.a. Perl, Python, JavaScript, Java, Scala und PHP Ideen der
funktionalen Programmierung von Haskell übernommen. Dazu gehören Funktionen höherer Ordnung wie map,
filter, u.s.w, Teile der Art, wie generische Programmierung implementiert wurde, und anderes.
Siehe auch
International Conference on Functional Programming Contest
Pugs (eine Perl-6-Implementierung in Haskell)
Literatur
Richard Bird: Introduction to Functional Programming using Haskell. 2. Auflage. Prentice Hall
Europe, 1998, ISBN 0-13-484346-0.
Marco Block, Adrian Neumann: Haskell-Intensivkurs: Ein kompakter Einstieg in die funktionale
Programmierung. Springer, Heidelberg u. a. 2011, ISBN 978-3-642-04717-6, doi:10.1007/978-3642-04718-3 (http://dx.doi.org/10.1007%2F978-3-642-04718-3) .
Paul Hudak: The Haskell school of expression: Learning functional programming through
multimedia. Cambridge University Press, Cambridge u. a. 2000, ISBN 0-521-64338-4 (Neuauflage:
The Haskell school of music (http://www.cs.yale.edu/homes/hudak/Papers/HSoM.pdf) , Version 2.2,
2012).
Ernst-Erich Doberkat: Haskell - Eine Einführung für Objektorientierte. Oldenbourg
Wissenschaftsverlag, München 2012, ISBN 978-3-486-71417-3.
John Hughes: Why functional programming matters. In: The Computer Journal. 32, Nr. 2, 1989,
S. 98–107 (Vorteile funktionaler Programmierung. Zeigt Formen der Modularisierung, die wesentlich auf
Funktionen höherer Ordnung und Bedarfsauswertung beruhen., chalmers.se
(http://www.cse.chalmers.se/~rjmh/Papers/whyfp.html) ).
Miran Lipovača: Learn you a Haskell for great good! A beginner’s guide. No Starch Press, San
Francisco 2011, ISBN 1-59327-283-9 (HTML-Fassung (http://learnyouahaskell.com/chapters) ).
de.wikipedia.org/wiki/Haskell_(Programmiersprache)
10/12
Bryan O’Sullivan, Don Stewart, John Goerzen: Real world Haskell. O’Reilly, Sebastopol 2008, ISBN
0596514980 (HTML-Fassung (http://book.realworldhaskell.org/) ).
Simon Peyton Jones (Hrsg.): Haskell 98 Language and Libraries: The Revised Report. Cambridge
University Press, 2003, ISBN 0-521-82614-4 (HTML-Version (http://www.haskell.org/onlinereport/) ).
Simon Thompson: Haskell: The craft of functional programming. 3. Auflage. Addison-Wesley,
Harlow und New York 2011, ISBN 978-0201882957.
Weblinks
Wikibooks: Haskell (englisch) – Lern- und Lehrmaterialien
Commons: Haskell (//commons.wikimedia.org/wiki/Category:Haskell?uselang=de) – Sammlung von
Bildern, Videos und Audiodateien
haskell.org (http://www.haskell.org/) – zentrale Anlaufstelle zu der Programmiersprache Haskell mit
Hinweisen zum Erlernen von Haskell (http://www.haskell.org/haskellwiki/Learning_Haskell)
interaktiver online Interpreter mit Tutorial (englisch) (http://tryhaskell.org/)
Einzelnachweise
1. Professor Paul Hudak’s Homepage
(http://web.archive.org/web/20110607204813/http://www.cs.yale.edu/homes/hudak-paul/) an der Yale
University
2. [Haskell] Announcing Haskell 2010 (http://www.haskell.org/pipermail/haskell/2009November/021750.html)
3. haskell.org (http://www.haskell.org/onlinereport/)
4. The Glasgow Haskell Compiler (http://www.haskell.org/ghc/) . Projekt-Website. Abgerufen am 9.
Januar 2010.
5. Hugs 98 (http://www.haskell.org/hugs/) . Projekt-Website. Abgerufen am 9. Januar 2010.
6. nhc98 (http://www.haskell.org/nhc98/) . Projekt-Website. Abgerufen am 9. Januar 2010.
7. Niklas Rojemo: nhc - Nearly a Haskell Compiler. (http://citeseerx.ist.psu.edu/viewdoc/download?
doi=10.1.1.38.5479&rep=rep1&type=pdf) Chalmers Tech Report, 1994.
8. Atze Dijkstra, Jeroen Fokker, S. Doaitse Swierstra: The architecture of the Utrecht Haskell compiler.
In: Haskell '09: Proceedings of the 2nd ACM SIGPLAN symposium on Haskell. ACM, New York,
NY, USA 2009, doi:10.1145/1596638.1596650, S. 93-104.
9. Bastiaan Heeren, Daan Leijen, Arjan van IJzendoorn: Helium, for learning Haskell. In: Haskell '03:
Proceedings of the 2003 ACM SIGPLAN workshop on Haskell. ACM, New York, NY, USA 2003,
doi:10.1145/871895.871902, S. 62–71.
Von „http://de.wikipedia.org/w/index.php?title=Haskell_(Programmiersprache)&oldid=111214243“
Kategorien: Haskell (Programmiersprache) Funktionale Programmiersprache
Diese Seite wurde zuletzt am 2. Dezember 2012 um 21:09 Uhr geändert.
Abrufstatistik
Der Text ist unter der Lizenz „Creative Commons Attribution/Share Alike“ verfügbar; zusätzliche
10.12.12
Haskell (Programmiersprache) – Wikipedia
Bedingungen können anwendbar sein. Einzelheiten sind in den Nutzungsbedingungen beschrieben.
Wikipedia® ist eine eingetragene Marke der Wikimedia Foundation Inc.
de.wikipedia.org/wiki/Haskell_(Programmiersprache)
12/12
Herunterladen