Programmieren in Haskell - WS 2013/2014

Werbung
Programmieren in
Haskell
Giegerich
Programmieren in Haskell
Organisation
WS 2013/2014
Programmiersprachen
Haskell
Syntax
Robert Giegerich
Universität Bielefeld
AG Praktische Informatik
October 30, 2013
Vordefinierte
Datentypen
Listen
Sprechstunden
Programmieren in
Haskell
Giegerich
Organisation
GZI-Arbeitsraum (V2-240)
Tutoren-Sprechstunden (V2-228)
http://www.techfak.uni-bielefeld.de/ags/pi/
lehre/AuDIWS13/#ueb
http://www.techfak.uni-bielefeld.de/ags/rbg/
de/gzi-tutoren.html
Programmiersprachen
Haskell
Syntax
Vordefinierte
Datentypen
Listen
Was sind Programmiersprachen?
Definition
Programmiersprachen regeln die textuelle (oder graphische)
Darstellung von Algorithmen, damit sie von einem Computer
ausgeführt werden können.
Was ist ein Algorithmus? Ein Computer? Was können sie
(nicht) leisten?
Siehe A&D-Vorlesung!
Programmieren in
Haskell
Giegerich
Organisation
Programmiersprachen
Haskell
Syntax
Vordefinierte
Datentypen
Listen
Wichtigste Kriterien für Programmiersprachen
Wie gut können WIR uns in der Sprache ausdrücken?
Wie gut kann der Computer die Programme ausführen?
Dabei hat “gut” zwei ganz verschiedene Bedeutungen ...
Ebenen der Programmierung
Entwicklung von Algorithmen:
Abgegrenzte und mathematisch wohldefinierte Aufgabe
Verwendung einer Programmiersprache
Einzelarbeit oder Kleingruppe
Kriterium: Korrektheit und Effizienz
alias Programmierung “im Kleinen”
Entwicklung von Software:
Größere Aufgabe mit diversen Funktionen
Markt- und Anwenderbezug, Termine!!
Arbeit in großen, auch verteilten Teams
Kombination verschiedener Programmiersprachen
Kriterium: Software-Lebenszyklus, Erweiterbarkeit
alias Programmierung “im Großen”
Programmieren in
Haskell
Giegerich
Organisation
Programmiersprachen
Haskell
Syntax
Vordefinierte
Datentypen
Listen
Ausbildungskonzept der TechFak
Ausgangspunkt: Informatiker müssen im Lauf ihres
Berufslebens mit einer Vielzahl von Programmiersprachen und
Softwaresystemen arbeiten.
Darauf müssen sie vorbereitet werden.
Zwei (sehr unterschiedliche) Programiersprachen im ersten
Jahr
1. Semester: Funktionale Programmierung (Haskell)
2. Semester: Objektorientierte Programmierung (Java)
3. Semester: Techniken der Projektentwicklung (TdPE)
4. Semester ff: projektspezifische Programmiersprachen
(Perl, Python, C und C++, Bellman’s GAP, u.v.a.)
Irgendwann: Scala (??)
Programmieren in
Haskell
Giegerich
Organisation
Programmiersprachen
Haskell
Syntax
Vordefinierte
Datentypen
Listen
Was gehört zu einer Programmiersprache?
Anwendungsbereich: Universell oder spezifisch?
Eine Sprachdefinition legt fest:
Syntax: Wie schreibt man etwas hin?
Semantik: Und was bedeutet das dann?
Pragmatik: Welche Zeichen und Konventionen werden
verwendet?
Ein Programmiersystem enthält
Compiler, Interpreter
Laufzeitsystem
Bibliotheken
Entwicklungsumgebung
Programmieren in
Haskell
Giegerich
Organisation
Programmiersprachen
Haskell
Syntax
Vordefinierte
Datentypen
Listen
Wie lernt man eine Programmiersprache
Programmieren in
Haskell
Giegerich
Man lernt
Organisation
Pragmatik: Gewöhnung
Programmiersprachen
Syntax: Beispiele, Feedback vom Compiler,
immer wieder Nachschlagen
Haskell
Semantik: Lehrbuch/Vorlesung, Übung/Diskussion
Ästhetik: Welches ist die “einfachste” Lösung einer
Aufgabe?
Syntax
Vordefinierte
Datentypen
Listen
Semantische Grundkonzepte von
Programmiersprachen
In den meisten Sprachen findet man
Module oder Pakete
Programmieren in
Haskell
Giegerich
Namen und Variablen
Organisation
Regeln der Sichtbarkeit und Gültigkeit
Programmiersprachen
vordefinierte Operationen, (arithmetische) Ausdrücke
Haskell
Anweisungen verschiedener Art (Iteration,
Fallunterscheidung)
Abstraktionsmechanismen: Klassen, Methoden,
Funktionen, Prozeduren, Parameter
vordefinierte Datentypen und Typ-Definitionen
Typ-Prüfung oder Typ-Inferenz
Rechenmodell
Syntax
Vordefinierte
Datentypen
Listen
Haskell
Haskell gehört zur Klasse der funktionalen
Programmiersprachen
seit 1990 vom “Haskell Committee” entwickelt für die
Public Domain
benannt nach dem Logiker Haskell B. Curry, aufbauend
auf den Sprachen ML und Miranda
“rein” funktional – alle Berechnungen durch Funktionen
beschrieben,
d.h. keine “Behälter”, keine Anweisungen, kein
vorher/nachher
nicht-strikte Auswertung
stark typisiert und polymorph; Typinferenz
Layout-sensitiv
Die wichtigsten Haskell-Implementierungen: Hugs
(Interpreter), GHC (Compiler), (GHCI Interpreter)
Programmieren in
Haskell
Giegerich
Organisation
Programmiersprachen
Haskell
Syntax
Vordefinierte
Datentypen
Listen
Funktionen als Bürger erster Klasse
Programmieren in
Haskell
Funktionen gibt es in allen Programmiersprachen.
In einer funktionalen Sprache sind Funktionen “first class
citizens”: Funktionen sind den Daten gleichberechtigt. Sie
können
Giegerich
Organisation
Programmiersprachen
Haskell
Argumente von (anderen) Funktionen sein
Ergebnisse von (anderen) Funktionen sein
anonym oder benannt sein
über beliebigen Datentypen definiert werden
1
Funktionen höherer Ordnung ersetzen “Kontrollstruktur”
map :: ( a -> b ) -> [ a ] - >[ b ]
Syntax
Vordefinierte
Datentypen
Listen
Haskell Pragmatik und Syntax
Wir schreiben in Haskell Literate Skripts
in der Programm-Datei steht ein beliebiger Text;
Programmieren in
Haskell
Giegerich
Zeilen, die mit > beginnen, enthalten Programmcode
Organisation
1
2
Mein erstes Programm
Programmiersprachen
Autor : Heinz Heinrichsen ( mit Hilfe von meiner
Oma )
Haskell
3
4
> gruss = " Hello world ! "
Vordefinierte
Datentypen
5
6
7
1
2
Geschafft !!!
= = = = = = = == = = = == = = = = = = = = = =
Tausend Gruesse
Autor : Die Oma vom Heinz
3
4
5
Syntax
> ngruesse n = concat ( take n hellos )
> hellos = " Hello World ! " : hellos
Listen
Namen versus Schlüsselwörter
Programmieren in
Haskell
Giegerich
Organisation
Namen bezeichnen Werte (aller Art) und sind frei wählbar
Schlüsselwörter strukturieren das Programm; sie dürfen nicht
als Namen verwendet werden
Namen und Schlüsselwörter dürfen nicht durch Leerzeichen
oder Zeilenende unterbrochen werden
Nicht zu verwechseln: Schlüsselwörter und vordefinierte Namen
Programmiersprachen
Haskell
Syntax
Vordefinierte
Datentypen
Listen
Schlüsselwörter
1
2
3
case class data default deriving do else
if import in infix infixl infixr instance
let module newtype of then type where _
Programmieren in
Haskell
Giegerich
Organisation
Vergleich
Programmiersprachen
Haskell
Sprache
#Keywords
Haskell
Scheme
C (C89)
Java
Ada
C++
21
23
32
50
72
74
Syntax
Vordefinierte
Datentypen
Listen
Groß- und Kleinschreibung in Namen
Programmieren in
Haskell
Modulname
erster Buchstabe großgeschrieben
Modulname == Dateiname
Datentypnamen: Großgeschrieben
Datentyp-Konstrukturen: Großgeschrieben
(z.B. Datentype Bool → Konstruktoren: True und False
Variablen, Funktionsnamen: Kleingeschrieben
Operatorzeichen → Infix-Schreibweise
Sonstige Funktionsnamen: Präfix-Schreibweise
Prioritäten und Assoziation definierbar
Giegerich
Organisation
Programmiersprachen
Haskell
Syntax
Vordefinierte
Datentypen
Listen
Keine (!) Anweisungen
Programmieren in
Haskell
Giegerich
keine Statements in Haskell
Organisation
keine Wertzuweisung, kein FOR, kein WHILE ...
→ da funktionale Programmiersprache
Programmiersprachen
Haskell
Es wird beschrieben, WAS berechnet werden soll, aber nicht
WIE. So wie in
(1 + f (2)) ∗ 32 ∗ (4 + g(5))
Hier ist nicht festgelegt, ob zuerst f (2), 32 , oder g(5)
berechnet wird
Syntax
Vordefinierte
Datentypen
Listen
Funktionsdefinitionen
1
2
3
4
Ein Haskell-Programm besteht im wesentlichen aus einer
Menge von Definitionen für Funktionen und Datentypen.
Einfache Funktionsgleichungen
> p x
= 5* x ^2 -7* x +9
> aba x y
= x ++ y ++ x
> f n
= if n ==0 then 1 else n * f (n -1)
> g x y z
= f (x * p y ) - z
5
6
7
8
9
> dnacomp b = if b ==
>
if b ==
>
if b ==
>
if b ==
Allgemein:
’A ’
’C ’
’G ’
’T ’
then
then
then
then
’T ’
’G ’
’C ’
’A ’
else
else
else
else
f p1 ... pk = Ausdruck, der p1 bis pk enthält
Programmieren in
Haskell
Giegerich
Organisation
Programmiersprachen
Haskell
Syntax
Vordefinierte
Datentypen
Listen
Mustergleichungen (pattern matching)
Programmieren in
Haskell
1
Mustergleichungen treffen Fallunterscheidungen auf der linken
Giegerich
Seite (und erlauben mehr als eine Gleichung)
>
error " illegal symbol in DNAOrganisation
"
2
3
4
> ff 0 = 1
> ff n = n * f (n -1)
Programmiersprachen
-- ueberlappende Muster
Haskell
Syntax
5
6
7
8
9
10
>
>
>
>
>
dnaComp
dnaComp
dnaComp
dnaComp
dnaComp
’A ’
’C ’
’G ’
’T ’
_
=
=
=
=
=
Vordefinierte
’T ’
Datentypen
Listen
’G ’
’C ’
’A ’
error " illegal symbol in DNA "
_ bezeichnet ein Argument, das nicht gebraucht wird
Fehlerbehandlung
Es gibt mehrere Möglichkeiten, Fehler zu behandeln in Haskell
Programmen (mindestens 8)
einfachster Mechanismus ist die Funktion error
error msg darf überall in einem Ausdruck stehen
msg ist ein String
error msg führt zum Programmabbruch mit Ausgabe von
msg
Die Funktion hat einen ganz besonderen Typ:
error :: String -> a
Example
1
2
3
> divide a b =
>
if b == 0 then error " divide by zero "
>
else div a b
Programmieren in
Haskell
Giegerich
Organisation
Programmiersprachen
Haskell
Syntax
Vordefinierte
Datentypen
Listen
Präfix, Infix, Postfix-Notation
Die Mathematik hat viele Schreibweisen für Ausdrücke
erfunden, um sie gut lesbar zu machen
Programmieren in
Haskell
Giegerich
Organisation
Programmiersprachen
Notation
Präfix
Infix
Postfix
Grafix
mathematisch
−1, f (x , y , z)
x < y , n2 , 2x + 5
0
n!,
q f √
3
1− y
Rb
in Haskell
-1, f x y z
x<y, nˆ2, 2*x+5
--root 3 (1 - (root 2 y))
integral a b f
a f (x ) dx
Präfix-Notation ohne Klammern ist der Regelfall in Haskell.
Was ist der Unterschied zwischen f a g b und f a (g b) ?
Haskell
Syntax
Vordefinierte
Datentypen
Listen
Operatoren
Zweistellige Funktionen mit Infix-Schreibweise nennt man
Operatoren.
Boolsche Operatoren sind vordefiniert:
|| oder
&& und
‘not‘
Vergleichsoperatoren: < <= == /= . . .
Arithmetik:
+ - * / ‘div‘ ‘mod‘
Zeichenreichen:
: ++
Operatoren sind reguläre Funktionen in Haskell; nur die
Infix-Notation und die gegebenen Prioritäten sind das
Besondere.
Example
Main> let (+) x y = x*y in 2+3
6
Programmieren in
Haskell
Giegerich
Organisation
Programmiersprachen
Haskell
Syntax
Vordefinierte
Datentypen
Listen
Prefix/Infix-Konversion
Funktionen als Operatoren
Operatoren als Funktionen
‘fn‘ konvertiert nach Infix
(op) konvertiert nach Prefix
Example
Programmieren in
Haskell
Giegerich
Organisation
Programmiersprachen
Haskell
Syntax
Main>
23
Main>
23
Test>
23
Test>
23
21 + 2
(+) 21 2
div 69 3
69 ‘div‘ 3
Vordefinierte
Datentypen
Listen
Prefix/Infix: Prioritäten
Programmieren in
Haskell
Giegerich
Flexible Anwendung von Funktionen
Organisation
Deklaration von Prioritäten möglich
meist geeignet vordefiniert –s. Haskell report
Funktionsanwendung in Präfix hat höchste Priorität
1
2
3
f x + g y * 2
ist
( f x ) + (( g y ) *2)
fuer einstelliges f und g
Achtung bei Definitionen :
Programmiersprachen
Haskell
Syntax
Vordefinierte
Datentypen
Listen
4
5
f ( x : xs ) ys = x : f xs ys
braucht Klammern !!
Bedingter Ausdruck
1
if expr1 then expr2 else expr3
Programmieren in
Haskell
Giegerich
Example
1
f a b
Organisation
= if a <= b then a +1 else b -2
Programmiersprachen
Haskell
Kein If-Statement!
if expr1 then expr2 ?
Fehler!
→ hier wäre der Wert des Ausdrucks im else-Fall nicht
definiert
Vergleichbar mit dem Bedingungsoperator in C/Java:
cond_expr ? expr2 : expr3
Syntax
Vordefinierte
Datentypen
Listen
Sichtbarkeitsbereiche
Programmieren in
Haskell
Giegerich
Alle (modernen) Programiersprachen haben
Sichtbarkeitsbereiche (scopes).
Jeder Name ist in dem Bereich sichtbar
in dem er definiert wurde
und in allen darin eingebetteteten Bereichen ...
... es sei denn, er wird verschattet
Scopes in einem Programm sind also “verschachtelt”.
Explizite Regeln gelten für Sichtbarkeit über Modulgrenzen
hinweg.
Organisation
Programmiersprachen
Haskell
Syntax
Vordefinierte
Datentypen
Listen
Layout und Abseitsregel
“Whitespace” sind Zeichen ohne Bedeutung:
Leerzeichen, NeueZeile, Kommentar
Haskell-Programme sind whitespace-sensitive
es gilt die Offside-Rule (Abseitsregel)
→ die Einrückung ist entscheidend
1
2
3
4
> dreh (x , y ) =
> schieb (x , y )=
> heb (x , y )
=
>
( -y , x )
( x +1 , y )
(x ,
y +1)
Giegerich
Organisation
Programmiersprachen
Haskell
in der Regel Verzicht auf Trennzeichen wie ; {},
aber explizite Verwendung von ; {} ist möglich
Example (richtig vs falsch)
Programmieren in
Haskell
Syntax
Vordefinierte
Datentypen
Listen
> dreh (x , y )= ( -y , x )
>
schieb (x , y )=( x +1 , y )
> heb (x , y )= (x ,
> y +1)
Layout definiert Sichtbarkeitsbereiche
Programmieren in
Haskell
Giegerich
Neue Bereiche entstehen nach of, where, let:
Organisation
Example (richtig)
1
2
3
4
5
6
>
>
>
>
>
>
show xs =
where
show ’
show ’
show ’
Programmiersprachen
" [ " ++ show ’ xs ++ " ] "
Haskell
Syntax
Nil
= ""
( Cons x Nil ) = show x
( Cons x xs ) = show x ++ " ,"
++ show ’ xs
Vordefinierte
Datentypen
Listen
Layout
Programmieren in
Haskell
Definitionen gleicher Stufe müssen in der gleichen Einrücktiefe
stehen
Example (falsch)
Giegerich
Organisation
Programmiersprachen
Haskell
1
2
3
4
5
6
>
>
>
>
>
>
show xs = " [ " ++ show ’ xs ++ " ] "
where
show ’ Nil
= ""
show ’ ( Cons x Nil ) = show x
show ’ ( Cons x xs ) = show x ++ " ,"
++ show ’ xs
Syntax
Vordefinierte
Datentypen
Listen
Explizite Scopes
Programmieren in
Haskell
Giegerich
1
2
3
4
5
Gleichwertig sind
Organisation
Example
Programmiersprachen
> f x = g x +
>
where { g
> f x = g x +
>
where g x
h x
h
x
h
=
=
x
= x * x ; h x = x + x }
x
x * x
x + x
Haskell
Syntax
Vordefinierte
Datentypen
Listen
Allgemeine Abseitsregel
Scopes sind Sichtbarkeitsbereiche von (Gruppen von)
Definitionen
Programmieren in
Haskell
Giegerich
alle Definitionen eines Scope stehen in der gleichen
Einrücktiefe
Organisation
tieferes Einrücken bedeutet Fortsetzung der aktuellen
Definitionszeile
Haskell
nach let, where, of, do bestimmt der nächste
Buchstabe die neue Einrücktiefe
Ausrücken nach links beendet den aktuellen Scope
Vorteile ??
Nachteile ??
Programmiersprachen
Syntax
Vordefinierte
Datentypen
Listen
Noch mehr Syntax
Programmieren in
Haskell
Giegerich
Organisation
Die folgenden Syntax-Elemente werden wir erst spaeter
kennelernen, wenn die entsprechenden Sprachkonstrukte
behandelt werden. Sie sind hier nur der Vollständigkeit halber
aufgeführt.
Programmiersprachen
Haskell
Syntax
Vordefinierte
Datentypen
Listen
Case-Ausdruck (pp.)
vielfache Fallunterscheidung
statt verschachtelte If-Expressions
überall wo ein Ausdruck stehen kann
Pattern matching
Programmieren in
Haskell
Giegerich
Organisation
Programmiersprachen
Haskell
1
2
3
4
5
case expr of
pat1 | guard1 -> expr1
pat2 | guard2 -> expr2
pat3 | guard3 -> expr3
...
Pattern kann leer sein
statt pat | True -> gilt auch die Konvention pat ->
otherwise als default
Syntax
Vordefinierte
Datentypen
Listen
Case-Ausdruck
Programmieren in
Haskell
Giegerich
Organisation
Example
1
2
3
4
5
> laststr xs = case reverse xs of
>
[]
-> " leer "
>
( l : ls ) | l == 1 -> " eins "
>
( l : ls ) | l == 2 -> " zwei "
>
otherwise
-> " ganz viele "
Programmiersprachen
Haskell
Syntax
Vordefinierte
Datentypen
Listen
Let Expression
let decl1
decl2
...
in expr
1
2
3
4
Kann überall dort stehen wo ein
Ausdruck stehen kann
lokaler Scope (Sichtbarkeitsbereich)
2
3
1
2
3
> func a b
>
>
Giegerich
Organisation
Programmiersprachen
Example
1
Programmieren in
Haskell
Haskell
= let square x = x * x
plus a b = a + b
in plus ( square a ) ( square b )
Versus:
> square x = x * x
> plus a b = a + b
> func a b = plus ( square a ) ( square b )
Hier sind plus und square auch außerhalb von func bekannt.
Syntax
Vordefinierte
Datentypen
Listen
Where-Notation
lokale Definitionen
bei Funktionsdefinitionen
case-Ausdrücken
Module-Definition . . .
Example
Programmieren in
Haskell
Giegerich
Organisation
Programmiersprachen
Haskell
1
2
3
> f x = square x + square x
>
where
>
square x = x * x
vs. let Ausdruck
notationelle Betonung
syntaktischer Zucker
where kann nicht überall stehen
Syntax
Vordefinierte
Datentypen
Listen
Where-Notation
Programmieren in
Haskell
Giegerich
Organisation
1
2
3
4
5
Schachtelungen auch möglich:
> foo x = ... f ...
>
where
>
f x = ... g ...
>
where
>
g x = ....
Programmiersprachen
Haskell
Syntax
Vordefinierte
Datentypen
Listen
Modul-Aufbau
Programmieren in
Haskell
Modulname
Imports
Definitionen
Giegerich
Organisation
1
2
> module Meinmodul
> where
Programmiersprachen
Haskell
3
4
Syntax
> import Data . List
Vordefinierte
Datentypen
5
6
> splits n = [ splitAt k [1.. n ] | k < -[1.. n -1]]Listen
Main> splits
[ ( [1
( [1,2
( [1,2,3
( [1,2,3,4
5
],[
],[
],[
],[
2,3,4,5]
3,4,5]
4,5]
5]
)
)
)
)
,
,
,
]
Wächter (Guards) in Funktionsdefinitionen (pp.)
1
2
3
4
> fn pat1 pat2 ...
>
| guard1 = expr1
>
| guard2 = expr2
>
...
syntaktische Zucker für Funktionsdefinitionen
Programmieren in
Haskell
Giegerich
Organisation
Programmiersprachen
Haskell
ersetzt geschachtelte if-Anweisungen
guards (Wächter) sind Ausdrücke (vom Typ Bool)
Example
1
2
3
4
howManyEqual n m p
| ( n == m ) && ( m == p )
= 3
| ( n == m ) || ( m == p ) || ( n == p ) = 2
| otherwise
= 0
Syntax
Vordefinierte
Datentypen
Listen
Pattern matching
Pattern Matching auf
natürlichen Zahlen
Werten
Datentyp-Konstruktoren
Joker _
2
3
Giegerich
Organisation
Programmiersprachen
Haskell
auf der linken Seite von Funktionsdefinitionen
Syntax
in case-Ausdrücken
Vordefinierte
Datentypen
Example
1
Programmieren in
Haskell
> take ’
:: Int -> [ a ] -> [ a ]
> take ’ ( n +1) ( a : as ) = a : take ’ n as
> take ’ _
_
= []
Listen
Pattern matching
In der Anwendung wird die erste Gleichung benutzt, deren
Muster auf die Argumente passen.
2
3
4
>
>
>
>
f
f
f
f
( a : b : c : d : ds )
( a : as )
( a :[])
[a]
=
=
=
=
...
...
...
...
7
8
Programmiersprachen
Haskell
Syntax
Vordefinierte
Datentypen
Listen
5
6
Giegerich
Organisation
Example
1
Programmieren in
Haskell
> g 0
> g 1
> g _
= ...
= ...
= ...
Wo es geht, wählt man die Muster einander ausschließend.
Typen in Haskell
Haskell verwendet strong typing:
Programmieren in
Haskell
Giegerich
Jeder Wert hat einen Typ; Funktionen dürfen nur auf
Argumente des richtigen Typs angewandt werden
Organisation
Typen können vom Compiler geprüft werden
Programmiersprachen
Typisierung kostet keinen Rechenaufwand zur Laufzeit
Haskell
Haskell verwendet parametrischen Typ-Polymorphismus
Funktionen können allgemeine Typen mit Typ-Parametern
haben; z.B.
map:: (a -> b) -> [a] -> [b]
Bei der Anwendung einer polymorphen Funktion
konkretisiert sich ihr Typ
Haskell verwendet Typ-Klassen – davon spaeter mehr.
Syntax
Vordefinierte
Datentypen
Listen
Datentypen
Programmieren in
Haskell
Ein Datentyp ist eine Mengen von Werten, worauf Operationen
(Funktionen) definiert werden können.
Giegerich
Organisation
eingebaute Datentypen sind vordefiniert und haben oft
eine besondere Notation
Programmiersprachen
benutzerdefinierte Datentypen werden durch
Typdefinitionen eingeführt; haben Standard-Notation
Syntax
Typdeklarationen geben zu neuen Namen den Typ ihres
Werts an
Listen
Typdeklarationen sind optional. Sie dienen hauptsächlich der
Lesbarkeit.
Haskell
Vordefinierte
Datentypen
Funktionstypen
1
1
2
3
4
1
2
Der wichtigste Datentyp ist die Funktion, allgemein
a -> b
Konkrete Funktionen haben speziellere Typen, z.B.
> power :: Int -> Int -> Int
> isqrt :: Int -> Float
> id ::
a -> a
> id x =
x
Mehrstellige Funktionen und Funktionen höherer Ordnung
ergeben sich, wenn man für a und b selbst wieder
Funktionstypen einsetzt
> (+):: Int -> Int -> Int
> (:):: a -> [ a ] -> [ a ]
3
4
> map :: (a - > b ) -> [ a ] -> [ b ]
map ist also eine zweistellige Funktion, deren erstes Argument
selbst eine Funktion ist
Programmieren in
Haskell
Giegerich
Organisation
Programmiersprachen
Haskell
Syntax
Vordefinierte
Datentypen
Listen
Gestaffelte Funktionen
Programmieren in
Haskell
Giegerich
1
1
1
Mehrstelligen Funktionen gibt man den “gestaffelten” Typ
a -> b -> c ... -> y -> z
-- 25 - stellig
was (per Definition von ->) das Gleiche ist wie
a -> ( b -> ( c ...( y -> z )...))
aber etwas anderes als
(a ,b ,c ,... , y ) -> z
Das letzte wäre eine 1-stellige Funktion mit einem 25-Tupel als
Argument.
Organisation
Programmiersprachen
Haskell
Syntax
Vordefinierte
Datentypen
Listen
Eingebaute Datentypen: Zahlen
Programmieren in
Haskell
Elementare eingebaute Datentypen in Haskell sind:
Ganze Zahlen (Integer, Int)
Funktionen darauf sind z.B.: +, -, *, div, mod, ^
Fließkommazahlen (Float, Double)
+, /, ^, sqrt
Konstanten können mehreren Typen angehören:
Wert
mögl. Typen
1, -5, 100, 0.314e1 Int, Integer, Float, Double
2.0, 2e3, 3.14e0
Float, Double
1,-5, 120
Int, Integer
Integer sind ganze Zahlen beliebiger Stellenzahl
Giegerich
Organisation
Programmiersprachen
Haskell
Syntax
Vordefinierte
Datentypen
Typklasse
Listen
Num
Fractional
Integral
Eingebaute Datentypen: Bool, Char, String
Programmieren in
Haskell
Giegerich
Wahrheitswerte (Bool): True, False
&&, ||, not
Zeichen (Char): ’a’, ’A’, ’\’ ...
Zeichenketten (String), wobei String = [Char]
"abraham", "2XG5", "" ...
Listen ([a])
[], :, ++, reverse, take, drop
Listen sind polymorph und kommen gleich noch ausführlicher!
Organisation
Programmiersprachen
Haskell
Syntax
Vordefinierte
Datentypen
Listen
Typen von Ausdrücken
Programmieren in
Haskell
Ausdrücke haben Typen:
1
2
3
4
5
6
7
8
9
Giegerich
Organisation
42
:: Int
3 + 4
:: Int
4.2
:: Float
True
:: Bool
" Hallo Welt ! " :: String -- bzw . [ Char ]
[1 ,2 ,3]
:: [ Int ]
[]
:: [ a ]
[[]]
:: [[ a ]]
Hier sind einige Typen spezieller als es sein muss!
Programmiersprachen
Haskell
Syntax
Vordefinierte
Datentypen
Listen
Typinferenz in Ausdrücken
Programmieren in
Haskell
Giegerich
Organisation
Hugs> :t (1+2)
1 + 2 :: Num a => a
Hugs> :t (4.2)
4.2 :: Fractional a => a
Hugs> :t 2/3
2 / 3 :: Fractional a => a
Klasse => ... nennt man einen Typkontext
Programmiersprachen
Haskell
Syntax
Vordefinierte
Datentypen
Listen
Typen einschränken
Durch explizite Typ-Angaben kann man den allgemeinsten Typ
einschränken:
Programmieren in
Haskell
Giegerich
Hugs> 2 / 3
0.6666666666666
Organisation
Programmiersprachen
Hier wird für 1 und 2 ein Typ der Klasse Fractional a
abgeleitet. Jetzt die Einschränkung:
Hugs> (2::Int)
ERROR - Cannot
*** Instance
*** Expression
/ (3::Int)
infer instance
: Fractional Int
: 2 / 3
Hugs> (2::Int) ‘div‘ (3::Int)
0
Haskell
Syntax
Vordefinierte
Datentypen
Listen
Typklassen
In Haskell sind Typen in Klassen organisiert. Typen sind dabei
Instanzen von Klassen.
Beispiele für Typklassen
Programmieren in
Haskell
Giegerich
Organisation
Eq Überprüfung auf Gleichheit. In der Klasse Eq sind die
Operationen == und /= definiert.
Instanzen z.B.: Int, Float, Double, String
Ord Ordnungsrelation. In der Klasse Ord sind die Operationen
<,>,<=,>= definiert.
Instanzen z.B.: Int, Float, Double, String
Num Umfasst die numerischen Typen, z.B. Int, Float, Double
Operationen: +,-,*
Show Werte eines Typs der Instanz der Klasse Show ist, lassen
sich ausgeben
Z.B. Int, Float, Double, String
Programmiersprachen
Haskell
Syntax
Vordefinierte
Datentypen
Listen
Definition von Typklassen
Programmieren in
Haskell
Giegerich
Natürlich kann man selbst
Typklassen neu definieren
Organisation
Programmiersprachen
Haskell
bestehende Typklassen erweitern
konkrete Datentypen zu Instanzen von Typklassen machen
Das entspricht in etwa den abstrakten Klassen oder Interfaces
in Java, die durch konkrete Klassen implementiert werden.
Syntax
Vordefinierte
Datentypen
Listen
Tupel-Typen
Notation ( a1, a2, a3, ... )
vordefinierte Funktionen:
fst
snd
...
Komponenten können verschiedene Typen haben
vs. Liste
Example
1
2
fst
:: (a , b ) -> a
fst (x , y ) = x
3
4
5
snd
:: (a , b ) -> a
snd (_ , y ) = y
Programmieren in
Haskell
Giegerich
Organisation
Programmiersprachen
Haskell
Syntax
Vordefinierte
Datentypen
Listen
Void
Programmieren in
Haskell
Giegerich
Organisation
Unit-Datentyp in Haskell: ()
Programmiersprachen
Haskell
einziges Element: ()
Syntax
vergleichbar mit void in C/Java
Vordefinierte
Datentypen
Listen
Listen in der funktionalen Programmierung
Programmieren in
Haskell
Listen gibt es in allen Programmiersprachen, aber in der
funktionalen Programmierung werden sie besonders viel
benutzt.
Dafür gibt es
einen polymorphen Datentyp für Listen aus Elementen von
beliebigem, aber gleichem Typ
viele vordefinierte Funktionen auf Listen
eine spezielle Notation für Listen,
Listenbeschreibungen ähnlich der mathematischen
Mengen-Notation
Giegerich
Organisation
Programmiersprachen
Haskell
Syntax
Vordefinierte
Datentypen
Listen
Der polymorphe Listen-Typ [a]
Notation:
[1,2,3,4] – geschönte Notation
1:2:3:4:[] – Standard-Notation mit Konstruktoren
(:) :: a -> [a] -> [a]
”Cons”
[] :: [a]
”Nil”
[1..10]
Typ-Notation: [a], [Int] usw.
Main> 1:2:3:4:[]
[1,2,3,4]
Example
1
2
3
> length ’
:: [ a ] -> Int
> length ’ []
= 0
> length ’ ( a : as ) = 1 + length ’ as
Programmieren in
Haskell
Giegerich
Organisation
Programmiersprachen
Haskell
Syntax
Vordefinierte
Datentypen
Listen
Listenbeschreibungen
Programmieren in
Haskell
1
2
3
4
1
2
Listenbeschreibungen sind der mathematischen
Giegerich
Mengen-Notation nachempfunden.
Beispiel:
Organisation
sm =
[ x | x <- " abraham " , x < ’i ’]
Programmiersprachen
pairs =
[( a , b +1) | a <- " aber " , b <- [1 ,2 ,3]]
Haskell
evenodd = [( a ,b , a + b ) | a <- [1..10] , b <- [11..20]
,
Syntax
even a == odd b ]
Vordefinierte
Allgemeine Form:
Datentypen
Listen
[ f x y ... | x <- X , cond x ,
y <- Y , cond x y , ...]
X, Y, ...: Listen, aus denen Elemente kommen
cond:
Bedingungen, die diese erfuellen muessen
f x y ...: Elemente der neuen Listen, die aus den
ausgewaehlten x, y,... berechnet werden
Listenbeschreibungen für Zahlenfolgen
Programmieren in
Haskell
1
2
3
4
5
6
Besonders komfortable Notation gibt es für Zahlenfolgen:
l1 = [1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,10]
l2 = [1..10]
l3 = [1..]
l4 = [1 ,5..42]
l5 = [1 ,5 ..]
l6 = [10 ,8 .. 1]
Aufsteigende und absteigende Zahlenfolgen;
die Differenz der beiden ersten Zahlen gibt die Schrittweite und
Richtung an,
.. bedeutet Fortsetzung, bis zum Endwert wenn angegeben,
sonst unendlich.
Giegerich
Organisation
Programmiersprachen
Haskell
Syntax
Vordefinierte
Datentypen
Listen
Mehr über Listen
Programmieren in
Haskell
Giegerich
Organisation
Programmiersprachen
Es folgen viele Beispiele von Funktionen über Listen.
Siehe Datei listintro.lhs
Haskell
Syntax
Vordefinierte
Datentypen
Listen
Herunterladen