Programmieren in Haskell

Werbung
Universität Bielefeld
Programmieren
in Haskell
Giegerich
Programmieren in Haskell
WS 2011/2012
Robert Giegerich
Universität Bielefeld
AG Praktische Informatik
October 30, 2013
Algebraic
Datatypes
Musik
Algebraische Datentypen
Universität Bielefeld
Programmieren
in Haskell
Neue Datentypen werden als algebraische Datentypen
eingeführt.
Werte des Datentyps sind Formeln, die aus Konstruktoren
zusammengesetzt sind
Konstruktoren sind Funktionen, die man deklarieren, aber
nicht definieren muss.
Konstruktornamen fangen mit Großbuchstaben an.
Algebraische Datentypen können polymorph sein und
Typ-Parameter haben.
Meistens sind sie rekursiv - ein Wert kann einen Teil-Wert
des gleichen Typs enthalten.
Giegerich
Algebraic
Datatypes
Musik
Beispiel
Universität Bielefeld
Programmieren
in Haskell
Giegerich
1
2
data Bool = True |
False
Algebraic
Datatypes
Musik
Beispiel
Universität Bielefeld
Programmieren
in Haskell
Giegerich
1
2
data Bool = True |
False
keine Typ-Parameter, nicht rekursiv, nur zwei Werte
Konstruktoren sind True und False
Algebraic
Datatypes
Musik
Beispiel
Universität Bielefeld
Programmieren
in Haskell
Giegerich
1
2
data Bool = True |
False
keine Typ-Parameter, nicht rekursiv, nur zwei Werte
Konstruktoren sind True und False
→ beide null-stellig (nullary (data) constructor)
Funktionen nutzen pattern matching auf den
Konstruktoren, z.B. der Operator &&:
1
2
False && y = False
True && y = y
Algebraic
Datatypes
Musik
Apropos Konstruktor
Universität Bielefeld
Programmieren
in Haskell
Giegerich
Algebraic
Datatypes
„Konstruktor“ meint immer (Daten-)Konstruktor.
Musik
Apropos Konstruktor
Universität Bielefeld
Programmieren
in Haskell
Giegerich
Algebraic
Datatypes
1
„Konstruktor“ meint immer (Daten-)Konstruktor.
Einen Typnamen mit Parametern nennt man gelegentlich
„Typ-Konstruktor“
data T a b = ...
Typ-Konstruktor T “konstruiert” aus Typen a und b den Typ
T a b
Musik
Beispiel
1
2
3
data Einheit
= Celsius
|
Fahrenheit |
Kelvin
Neuer Typ mit genau drei Werten.
Universität Bielefeld
Programmieren
in Haskell
Giegerich
Algebraic
Datatypes
Musik
Beispiel
1
2
3
1
data Einheit
= Celsius
|
Fahrenheit |
Kelvin
Neuer Typ mit genau drei Werten.
data Temperatur = Temp Float Einheit
Universität Bielefeld
Programmieren
in Haskell
Giegerich
Algebraic
Datatypes
Musik
Beispiel
1
2
3
1
data Einheit
= Celsius
|
Fahrenheit |
Kelvin
Neuer Typ mit genau drei Werten.
data Temperatur = Temp Float Einheit
(Einziger) Konstruktor Temp hat zwei Argumente, deren
Typen deklariert werden.
Universität Bielefeld
Programmieren
in Haskell
Giegerich
Algebraic
Datatypes
Musik
Beispiel
1
2
3
1
data Einheit
= Celsius
|
Fahrenheit |
Kelvin
Neuer Typ mit genau drei Werten.
Universität Bielefeld
Programmieren
in Haskell
Giegerich
Algebraic
Datatypes
Musik
data Temperatur = Temp Float Einheit
(Einziger) Konstruktor Temp hat zwei Argumente, deren
Typen deklariert werden.
1
2
data Temp = Temp Float Einheit -- erlaubt und
-- ueblich !
Beispiel
1
2
3
1
data Einheit
= Celsius
|
Fahrenheit |
Kelvin
Neuer Typ mit genau drei Werten.
Universität Bielefeld
Programmieren
in Haskell
Giegerich
Algebraic
Datatypes
Musik
data Temperatur = Temp Float Einheit
(Einziger) Konstruktor Temp hat zwei Argumente, deren
Typen deklariert werden.
1
2
data Temp = Temp Float Einheit -- erlaubt und
-- ueblich !
→ Typkonstruktoren und (Daten-)Konstruktoren haben
getrennte Namensräume
Beispiel
Universität Bielefeld
Programmieren
in Haskell
Giegerich
1
Temp 506 Kelvin
:: Temperatur
Algebraic
Datatypes
Musik
Beispiel
Universität Bielefeld
Programmieren
in Haskell
Giegerich
1
Temp 506 Kelvin
:: Temperatur
celsius2kelvin
celsius2kelvin t
:: Float -> Temperatur
= Temp ( t + 273.15) Kelvin
Algebraic
Datatypes
Musik
1
2
3
4
5
6
kel vin2fahrenheit
:: Float -> Temperatur
kel vin2fahrenheit t =
Temp ( t *9/5 -459.67) Fahrenheit
Das Beispiel ist inkonsequent, weil das Argument selbst nicht
vom Typ Temperatur ist.
Beispiel
Universität Bielefeld
Programmieren
in Haskell
Giegerich
1
2
3
4
5
6
7
8
Temperatur-Umrechnung:
conv :: Temperatur -> Einheit -> Temperatur
conv ( Temp t Celsius ) Celsius
=
Temp t Celsius
conv ( Temp t Celsius ) Kelvin
=
Temp ( t + 273.15) Kelvin
conv ( Temp t Kelvin ) Fahrenheit =
Temp ( t *9/5 -459.67) Fahrenheit
...
Algebraic
Datatypes
Musik
Algebraische Datentypen
Universität Bielefeld
Programmieren
in Haskell
Giegerich
Allgemeine Form der Deklaration:
data T a1 . . . am = C1 t11 . . . t1n1
...
Cr tr 1 . . . trnr
|
|
Algebraic
Datatypes
Musik
Algebraische Datentypen
Universität Bielefeld
Programmieren
in Haskell
Giegerich
Allgemeine Form der Deklaration:
data T a1 . . . am = C1 t11 . . . t1n1
...
Cr tr 1 . . . trnr
T Typkonstruktor
Ci (Daten-)Konstruktoren
ai Typvariablen
tij Typen oder Typvariablen
|
|
Algebraic
Datatypes
Musik
Beispiel: Listen
Universität Bielefeld
Programmieren
in Haskell
Giegerich
1
2
Wenn man Listen noch einführen müßte ...
data List a = Cons a ( List a ) |
Nil
Algebraic
Datatypes
Musik
Beispiel: Listen
Universität Bielefeld
Programmieren
in Haskell
Giegerich
1
2
Wenn man Listen noch einführen müßte ...
data List a = Cons a ( List a ) |
Nil
polymorhper Typ (Typ-Parameter a)
→ Algebraischer Datentyp List ist rekursiv definiert
Algebraic
Datatypes
Musik
Beispiel: Listen
Universität Bielefeld
Programmieren
in Haskell
Giegerich
1
2
Wenn man Listen noch einführen müßte ...
data List a = Cons a ( List a ) |
Nil
polymorhper Typ (Typ-Parameter a)
→ Algebraischer Datentyp List ist rekursiv definiert
eingebaute Listentyp erlaubt syntaktischen Zucker:
: — „Cons“als Infix-Operator
[] — „Nil“
[] — Typ-Konstruktor, etwa in [Int]
Spezielle Listen-Notationen
Algebraic
Datatypes
Musik
Beispiel: Listen
Example
Universität Bielefeld
Programmieren
in Haskell
Giegerich
[1..5] = [1,2,3,4,5] = 1:2:3:4:5:[]
Algebraic
Datatypes
Musik
Beispiel: Listen
Universität Bielefeld
Programmieren
in Haskell
Example
Giegerich
[1..5] = [1,2,3,4,5] = 1:2:3:4:5:[]
Algebraic
Datatypes
Cons
Musik
1
Cons
2
Cons
3
Cons
4 Cons
5 Nil
Beispiel: Listen
Universität Bielefeld
Programmieren
in Haskell
Example
Giegerich
[1..5] = [1,2,3,4,5] = 1:2:3:4:5:[]
Algebraic
Datatypes
:
Cons
Musik
1
1
Cons
2
2
Cons
3
:
Cons
4 Cons
5 Nil
:
3
:
4
:
5 []
Elementare Funktionen auf Listen
Universität Bielefeld
Programmieren
in Haskell
Die meisten kennen wir bereits:
Giegerich
head, tail
Algebraic
Datatypes
length
Musik
sum, product
enumFromTo
append
reverse
take, drop
map
filter
concat, concatMap
siehe Tafel
Beispiel: Maybe
1
2
data Maybe a = Just a |
Nothing
Universität Bielefeld
Programmieren
in Haskell
Giegerich
Algebraic
Datatypes
Musik
Beispiel: Maybe
1
2
data Maybe a = Just a |
Nothing
Konstruktor Just ist ein-stellig
Typvariable a als Parameter
Universität Bielefeld
Programmieren
in Haskell
Giegerich
Algebraic
Datatypes
Musik
Beispiel: Maybe
1
2
data Maybe a = Just a |
Nothing
Konstruktor Just ist ein-stellig
Typvariable a als Parameter
Eine Form der Fehlerbehandlung bzw. Vorbeugung, wenn
eine Funktion ein Ergebnis liefert, das nicht in jedem Fall
existiert
Universität Bielefeld
Programmieren
in Haskell
Giegerich
Algebraic
Datatypes
Musik
Beispiel: Maybe
1
2
data Maybe a = Just a |
Nothing
Konstruktor Just ist ein-stellig
Typvariable a als Parameter
Eine Form der Fehlerbehandlung bzw. Vorbeugung, wenn
eine Funktion ein Ergebnis liefert, das nicht in jedem Fall
existiert
1
2
3
> divide a b =
>
if b == 0 then error " divide by zero "
>
else div a b
Universität Bielefeld
Programmieren
in Haskell
Giegerich
Algebraic
Datatypes
Musik
Beispiel: Maybe
1
2
data Maybe a = Just a |
Nothing
Konstruktor Just ist ein-stellig
Typvariable a als Parameter
Eine Form der Fehlerbehandlung bzw. Vorbeugung, wenn
eine Funktion ein Ergebnis liefert, das nicht in jedem Fall
existiert
1
2
3
1
2
3
> divide a b =
>
if b == 0 then error " divide by zero "
>
else div a b
Mit Maybe:
> divide a b
>
| b == 0
= Nothing
>
| otherwise
= Just ( div a b )
Universität Bielefeld
Programmieren
in Haskell
Giegerich
Algebraic
Datatypes
Musik
Beispiel: Maybe
Universität Bielefeld
Programmieren
in Haskell
Giegerich
1
Typ von divide:
divide :: ( Num a ) = > a -> a -> Maybe a
Algebraic
Datatypes
Musik
Beispiel: Maybe
Universität Bielefeld
Programmieren
in Haskell
Giegerich
1
1
2
3
4
Typ von divide:
divide :: ( Num a ) = > a -> a -> Maybe a
Pattern matching:
f a b = extract ( divide a b ) + ...
where
extract ( Just x ) = x
extract Nothing
= 0
Was ist der Typ von extract?
Algebraic
Datatypes
Musik
Typsynonyme (Nachtrag zum Haskell Typsystem)
Universität Bielefeld
Programmieren
in Haskell
1
2
3
1
Neue Typnamen durch Typsynonyme:
type Pair a b = (a , b )
type Triple a b c = (a ,b , c )
type OrdList a = [ a ]
definiert neue Namen, genannt Typ-Synonyme, für bereits
existieeremde Typen; hier im Beispiel für existierende
Tupel-Typen und Listen. Dient ausschliesslich der
Dokumentation.
newtype MyList a = [ a ]
führt ebenfalls einen NEUEN Typen analog zu [a] ein, der
aber nicht als typgleich betrachtet wird. Verhindert
gegenseitige Verwechslung von [a] und MyList a.
Giegerich
Algebraic
Datatypes
Musik
Derived instance declarations
Universität Bielefeld
Programmieren
in Haskell
Optionale deriving Form:
Giegerich
data T a1 . . . am = C1 t11 . . . t1n1
...
Cr tr 1 . . . trnr
deriving (k1 , . . . , ku )
|
|
Algebraic
Datatypes
Musik
Derived instance declarations
Universität Bielefeld
Programmieren
in Haskell
Optionale deriving Form:
Giegerich
data T a1 . . . am = C1 t11 . . . t1n1
...
|
|
Cr tr 1 . . . trnr
deriving (k1 , . . . , ku )
kx Typklassen
für bestimmte Klassen können Instanzen automatisch
erzeugt werden
das heißt, alle Operationen der Klassen werden auf dem
neuen Typ T automatisch implementiert.
Algebraic
Datatypes
Musik
Derived instance declarations
Universität Bielefeld
Programmieren
in Haskell
Optionale deriving Form:
Giegerich
data T a1 . . . am = C1 t11 . . . t1n1
...
|
|
Cr tr 1 . . . trnr
deriving (k1 , . . . , ku )
kx Typklassen
für bestimmte Klassen können Instanzen automatisch
erzeugt werden
das heißt, alle Operationen der Klassen werden auf dem
neuen Typ T automatisch implementiert.
→ einfacher als explizite Definition, die auch möglich ist
Algebraic
Datatypes
Musik
... deriving ...
Universität Bielefeld
Programmieren
in Haskell
Giegerich
Algebraic
Datatypes
Example
1
2
3
Musik
data Maybe a = Nothing |
Just a
deriving ( Eq , Ord , Read , Show )
Damit sind Operationen wie == oder < auf dem Typ Maybe
implementiert.
Modellierung von Musik
Universität Bielefeld
Programmieren
in Haskell
Giegerich
cis
dis
fis
gis
ais
cis
dis
fis
gis
ais
des
es
ges
as
b
des
es
ges
as
b
Algebraic
Datatypes
Musik
c
d
e
f
g
a
h
c
d
e
f
Quelle: http://commons.wikimedia.org/wiki/File:Klaviatur.svg, Public Domain
g
a
h
Modellierung von Musik
1
2
Universität Bielefeld
> module Musik where
> import R a t i o
Programmieren
in Haskell
Giegerich
3
4
5
> infixr 7 :∗:
> i n f i x r 6 :+:
Algebraic
Datatypes
6
7
8
Musik
> type G a n z e Z a h l
> type Bruch
= Int
= Ratio Int
> type Ton
> type Dauer
= GanzeZahl
= Bruch
9
10
11
12
13
14
15
16
17
18
19
20
> data Musik
=
>
Note
Ton
Dauer
>
Pause Dauer
>
Musik
:∗:
Musik
>
Musik
:+:
Musik
>
Instr
I n s t r u m e n t Musik
>
Tempo G a n z e Z a h l
Musik
>
deriving
|
|
|
|
|
−− h i n t e r e i n a n d e r
−− g l e i c h z e i t i g
−− S c h l a e g e p r o Minute
Show
Modellierung von Musik
Universität Bielefeld
Programmieren
in Haskell
Giegerich
22
23
24
147
148
149
150
151
> data Instrument =
>
A co usticGrand Pi an o
|
>
B ri ghtAcousti cP i a no |
...
>
TelephoneRing
|
>
Helicopter
|
>
Applause
|
>
Gunshot
>
deriving ( Show , Enum )
Algebraic
Datatypes
Musik
Modellierung von Musik
Universität Bielefeld
Programmieren
in Haskell
Giegerich
Sieben Ganztöne: c d e f g a h
Halbtöne über den Tönen: cis dis eis (= f) fis gis ais his
(=c)
Halbtöne unter den Tönen: ces (=h) des es fes (=e) ges
as b
c
cis
dis
fis
gis
ais
cis
dis
fis
gis
ais
des
es
ges
as
b
des
es
ges
as
b
d
e
f
g
a
h
c
d
e
f
g
a
h
Algebraic
Datatypes
Musik
Modellierung von Musik
19
Universität Bielefeld
> module M u s i k H e l p e r where
Programmieren
in Haskell
20
21
Giegerich
> import Musik
22
Algebraic
Datatypes
23
24
25
> ce , c i s , des , de , d i s , es , eh , e i s , f e s
> e f , f i s , ges , ge , g i s , as , ah , a i s , be , ha , h i s
c
cis
dis
fis
gis
ais
cis
dis
fis
gis
ais
des
es
ges
as
b
des
es
ges
as
b
d
e
f
g
a
h
c
d
e
f
g
a
h
: : TonMusik
: : Ton
Modellierung von Musik
19
Universität Bielefeld
> module M u s i k H e l p e r where
Programmieren
in Haskell
20
21
Giegerich
> import Musik
22
Algebraic
Datatypes
23
24
25
> ce , c i s , des , de , d i s , es , eh , e i s , f e s
> e f , f i s , ges , ge , g i s , as , ah , a i s , be , ha , h i s
26
27
28
29
30
31
32
33
>
>
>
>
>
>
>
ce
de
eh
ef
ge
ah
ha
=
=
=
=
=
=
=
0
2
4
5
7
9
11
;
;
;
;
;
;
;
cis
dis
eis
fis
gis
ais
his
=
=
=
=
=
=
=
1
3
5
6
8
10
12
;
;
;
;
;
;
des
es
fes
ges
as
be
=
=
=
=
=
=
1
3
4
6
8
10
: : TonMusik
: : Ton
Formeln, die Musik bedeuten
1
2
3
Note
0 (1/4)
Note 24 (1/1)
Pause
(1/16)
Universität Bielefeld
-- Viertelnote tiefes C
-- ganze Note
c’
-- Sechzehntelpause
4
5
6
Programmieren
in Haskell
Giegerich
Algebraic
Datatypes
Musik
Note 24 (1/4) :*: Note 26 (1/4) :*: Note 28 (1/4)
-- Anfang der C - Dur Tonleiter (c
7
8
9
Note 24 (1/4) :+: Note 28 (1/4) :+: Note 31 (1/4)
-- C - Dur Akkord (c ,e , g )
10
11
12
13
14
Tempo
Tempo
Instr
Instr
70 m
180 m
Oboe m
VoiceAahs m
-----
Musik
Musik
Musik
Musik
m
m
m
m
als Adagio
als Presto
von Oboe gespielt
gesummt
Abkürzungen
35
Universität Bielefeld
> gP , hP , vP , aP , sP :: Musik
Programmieren
in Haskell
Giegerich
36
37
38
39
40
41
>
>
>
>
>
gP
hP
vP
aP
sP
=
=
=
=
=
Pause
Pause
Pause
Pause
Pause
(1/1)
(1/2)
(1/4)
(1/8)
(1/16)
Algebraic
Datatypes
Musik
Abkürzungen
35
Universität Bielefeld
> gP , hP , vP , aP , sP :: Musik
Programmieren
in Haskell
Giegerich
36
41
43
> adagio , andante , allegro , presto :: GanzeZahl
38
39
40
gP
hP
vP
aP
sP
=
=
=
=
=
Pause
Pause
Pause
Pause
Pause
(1/1)
(1/2)
(1/4)
(1/8)
(1/16)
Algebraic
Datatypes
>
>
>
>
>
37
44
45
46
47
48
>
>
>
>
adagio = 70
andante = 90
allegro = 140
presto = 180
Musik
Abkürzungen
Universität Bielefeld
Programmieren
in Haskell
Giegerich
50
> c’ , d’ , e’ , f ’ , g’ , a’ , h’ , c’ ’
51
52
53
54
55
56
57
58
59
: : Dauer −> Musik
Algebraic
Datatypes
Musik
>
>
>
>
>
>
>
>
c’
d’
e’
f’
g’
a’
h’
c’’
u
u
u
u
u
u
u
u
=
=
=
=
=
=
=
=
Note
Note
Note
Note
Note
Note
Note
Note
( c e +24)
( de +24)
( eh +24)
( e f +24)
( ge +24)
( ah +24)
( ha +24)
( c e +36)
u
u
u
u
u
u
u
u
Zusammengesetzte Klänge
Universität Bielefeld
Programmieren
in Haskell
61
> c DurTon i ka : : Musik
62
63
> c DurTon i ka = c ’ ( 1 / 1 ) : + : e ’ ( 1 / 1 ) : + : g ’ ( 1 / 1 )
Giegerich
Algebraic
Datatypes
Musik
Zusammengesetzte Klänge
Universität Bielefeld
Programmieren
in Haskell
61
> c DurTon i ka : : Musik
62
63
> c DurTon i ka = c ’ ( 1 / 1 ) : + : e ’ ( 1 / 1 ) : + : g ’ ( 1 / 1 )
66
67
68
Algebraic
Datatypes
Musik
64
65
Giegerich
> cDurSkala
>
c ’ (3/8)
>
>
= Tempo a l l e g r o (
: ∗ : d ’ (1/8) : ∗ : e ’ (3/8) : ∗ : f ’ (4/8)
: ∗ : g ’ (1/8) : ∗ : a ’ (1/4) : ∗ : h ’ (1/8)
: ∗ : c ’ ’ (1/2))
Zusammengesetzte Klänge
Universität Bielefeld
Programmieren
in Haskell
61
> c DurTon i ka : : Musik
62
63
> c DurTon i ka = c ’ ( 1 / 1 ) : + : e ’ ( 1 / 1 ) : + : g ’ ( 1 / 1 )
66
67
68
70
71
> cDurSkala
>
c ’ (3/8)
>
>
= Tempo a l l e g r o (
: ∗ : d ’ (1/8) : ∗ : e ’ (3/8) : ∗ : f ’ (4/8)
: ∗ : g ’ (1/8) : ∗ : a ’ (1/4) : ∗ : h ’ (1/8)
: ∗ : c ’ ’ (1/2))
> durDreiklang t
>
= Note t ( 1 / 1 ) : + : Note ( t +4) ( 1 / 1 )
: + : Note ( t +7) ( 1 / 1 )
72
73
74
Algebraic
Datatypes
Musik
64
65
Giegerich
> m o l l D r e i k l a n g t = Note t ( 1 / 1 ) : + : Note ( t +3) ( 1 / 1 )
>
: + : Note ( t +7) ( 1 / 1 )
Transponierung
Universität Bielefeld
Programmieren
in Haskell
Giegerich
79
> transponiere
Algebraic
Datatypes
: : Ton −> Musik −> Musik
Musik
80
81
82
83
84
85
86
>
>
>
>
>
>
t r a n s p o n i e r e i ( Pause d )
=
t r a n s p o n i e r e i ( Note t d ) =
t r a n s p o n i e r e i (m1 : ∗ : m2) =
:∗:
t r a n s p o n i e r e i (m1 : + : m2) =
:+:
Pause d
Note ( t+i ) d
( transponiere
( transponiere
( transponiere
( transponiere
i
i
i
i
m1)
m2)
m1)
m2)
Verschiedenes
Universität Bielefeld
Programmieren
in Haskell
Giegerich
Algebraic
Datatypes
92
93
> wdh
: : Musik −> Musik
> wdh m = m : ∗ : m
94
95
96
> ad_infinitum
: : Musik −> Musik
> ad_infinitum m = m : ∗ : ad_infinitum m
97
98
> einsatz
d m = ( Pause d ) : ∗ : m
Musik
Bruder Jakob: Text
Universität Bielefeld
Programmieren
in Haskell
Bruder Jakob, Bruder Jakob
Schläfst du noch? Schläfst du noch?
||: Hörst du nicht die Glocken? :||
Ding dang dong, ding dang dong.
Quelle: http://de.wikipedia.org/w/index.php?title=Datei:
FrereJacques1pt.png&filetimestamp=20070819210216, Public Domain
Giegerich
Algebraic
Datatypes
Musik
Herunterladen