Kapitel 3

Werbung
3Datentypdefi
Programmiersprache
3 Eine
Eineeinfache
einfache
Programmiersprache3.1 Datentypen 3.1.1
nitionen3.1.2 Typsynonyme 3.1.3 Typdeklarationen, Typprüfung
und
Typinferenz
3.1.4
Typklassen und Typkontexte
3.2 Wertdefi
nitionen
3.2.1
Musterund
Funktionsbindungen
3.2.2
Bewachte
Gleichungen
3.2.3
GleichungenVollständige
mit lokalen Defi
3.2.4
Das3.3
Rechnen
mit
Gleichungen3.2.5
undnitionen
disjunkte
Muster
Ausdrücke
3.3.1
Variablen,
Funktionsanwendungen
und
Konstruktoren3.3.2
Fallunterscheidungen
3.3.3 Funktionsausdrücke
3.3.4 Lokale
Definitionen
3.4
Anwendung:
Binärbäume
3.5
Vertiefung:
Rechnen
in
Haskell
3.5.1
Eine Kernsprache/Syntaktischer
Zucker
3.5.2 Auswertung von 3.5.4
Fallunterscheidungen
3.5.3
Auswertung
von Funktionsanwendungen
Auswertung
von
lokalen
Defi
nitionen
3
Eine
einfache
Programmiersprache
3.1
Datentypen
3.1.1
Datentypdefi
nitionen3.1.2
Typsynonyme
3.1.3
Typdeklarationen,
Typprüfung
und3.2.1
Typinferenz
3.1.4
Typklassen
und
Typkontexte
3.2
Wertdefi
nitionen
Musterund
Funktionsbindungen
3.2.2
Bewachte
Gleichungen
3.2.3
Gleichungen
mit
lokalen
Defi
nitionen
3.2.4
Das
Rechnen
mit
Gleichungen3.2.5
Vollständige
und
disjunkte
Muster
3.3 AusdrückeFallunterscheidungen
3.3.1 Variablen, Funktionsanwendungen
und
Konstruktoren3.3.2
3.3.3
Funktionsausdrücke
3.3.4
Lokale
Defi
nitionen
3.4
Anwendung:
Binärbäume
3.5
Vertiefung:
Rechnen
in Haskell
3.5.1
Eine Kernsprache/Syntaktischer
Zucker
3.5.2
Auswertung
von
Fallunterscheidungen
3.5.3
Auswertung
von 3
Funktionsanwendungen
3.5.4
Auswertung
von
lokalen
Defi
nitionen
Eine
einfache
Programmiersprache
3.1
Datentypen
3.1.1
Datentypdefi
nitio
nen3.1.2
Typsynonyme
3.1.3
Typdeklarationen,
Typprüfung
und
Typinferenz
3.1.4
Typklassen und Typkontexte
3.2 Wertdefi
nitionen
3.2.1
Muster- und
Funktionsbindungen
3.2.2
Bewachte
Gleichungen
3.2.3
Gleichungen
mit
lokalen
Defi
nitionen
3.2.4
Das
Rechnen
mit
Gleichungen3.2.5
Vollständige
und disjunkte
Muster
3.3 Ausdrücke 3.3.1
Variablen,
Funktionsanwendungen
und
Konstruktoren3.3.2
Fallunterscheidungen
3.3.3
Funktionsausdrücke
3.3.4
Lokale
Defi
nitionen
3.4
Anwendung:
Binärbäume
3.5
Vertiefung:
Rechnen
in
Haskell
3.5.1
Eine
Kernsprache/
Syntaktischer
Zucker
3.5.2
Auswertung
von
Fallunterscheidungen
3.5.3
Auswertung
von
Funktionsanwendungen
3.5.4 Auswertung
von lokalen
Defi
nitionen
3
Eine
einfache
Programmiersprache
3.1
Datentypen
3.1.1
Datentypdefi
nitionen3.1.2
Typsynonyme
3.1.3
Typdeklarationen,
Typprüfung
und
Typinferenz
3.1.4
Typklassen und Typkontexte
3.2 Wertdefi
nitionen
3.2.1
Musterund
Funktionsbindungen
3.2.2
Bewachte
Gleichungen
3.2.3
Gleichungen
mit
lokalen
Defi
nitionen
3.2.4
Das
Rechnen
mit
Gleichungen3.2.5
Vollständige
und
disjunkte
Muster
3.3
Ausdrücke
3.3.1
Variablen, Funktionsanwendungen
und Konstruktoren3.3.2
Fallunterscheidungen
3.3.3 Funktionsausdrücke
3.3.4 in
Lokale
Definitionen
3.4
Anwendung:
Binärbäume
3.5
Vertiefung:
Rechnen
Haskell
3.5.1
Eine
Kernsprache/Syntaktischer
Zucker
3.5.2
Auswertung
von 3.5.4
Fallunterscheidungen
3.5.3
Auswertung
von
Funktionsanwendungen
Auswertung
von lokalen
Definitionen
3 Eine einfache
Programmiersprache
3.1
Datentypen
3.1.1
Datentypdefi
nitionen3.1.2
Typsynonyme
3.1.3
Typdeklarationen,
Typprüfung
und
Typinferenz
3.1.4
Typklassen
und
Algorithmen
und
Datenstrukturen
Typkontexte
3.2
Wertdefi
nitionen
3.2.1
Musterund
Funktionsbindungen
3.2.2
Bewachte
Gleichungen
3.2.3 Gleichungen
mit lokalen
DefiInitionen
3.2.4
Das
Rechnen
mit
Gleichungen3.2.5
Vollständige
und
disjunkte
Prof. Dr. Funktionsanwendungen
Robert
Giegerich
· Universität
Muster
3.3 AusdrückeFallunterscheidungen
3.3.1 Variablen,
und Bielefeld · WS 2004/2005
Konstruktoren3.3.2
3.3.3
Funktionsausdrücke
3.3.4
Lokale
Definitionen
3.4 Anwendung:
Binärbäume 3.5
Vertiefung:
Rechnen
in Haskell
3.5.1
Eine
Kernsprache/Syntaktischer
Zucker
3.5.2
Auswertung
von
Fallunterscheidungen
3.5.3
Auswertung
von 3
Funktionsanwendungen
3.5.4
Auswertung
von
lokalen
Defi
nitionen
Eine
einfache
Programmiersprache
3.1 Datentypen
3.1.1 Datentypdefi
nitio
nen3.1.2
Typsynonyme
3.1.3 Typdeklarationen,
Typprüfung
und
Typinferenz
3.1.4
Typklassen
und
Typkontexte
3.2
Wertdefi
nitionen
3.2.1
Musterund
Funktionsbindungen
3.2.2
Bewachte
Gleichungen
3.2.3 Gleichungen
mit
lokalen Defi
nitionen
3.2.4
Das 3.3
Rechnen
mit Gleichungen3.2.5
Vollständige
und
disjunkte
Muster
Ausdrücke
3.3.1
Variablen,
Funktionsanwendungen
und
Konstruktoren3.3.2
Fallunterscheidungen
3.3.3
Funktionsausdrücke
3.3.4
Lokale
Defi
nitionen
Anwendung:
Binärbäume
3.5
Vertiefung:
Rechnen
in von
Haskell
3.5.13.4
Eine
Kernsprache/
Syntaktischer
Zucker
3.5.2
Auswertung
Fallunterscheidungen
3.5.3
Auswertung
von
Funktionsanwendungen
3.5.4
Auswertung
von
lokalen
Defi
nitionen Eine
einfache Programmiersprache
3.1 DatentypenTypprüfung
3.1.1
Datentypdefi
nitionen3.1.2
Typsynonyme
3.1.3 Typdeklarationen,
und
Typinferenz
3.1.4
Typklassen
und
Typkontexte
3.2
Wertdefi
nitionen
3.2.1
Musterund Funktionsbindungen
3.2.2
Bewachte
Gleichungen
3.2.3
Gleichungen
mit
lokalen
Defi
nitionen
3.2.4
Das
Rechnen
mit
Gleichungen3.2.5
Vollständige und disjunkte
Muster 3.3 Ausdrücke
3.3.1 Variablen, Funktionsanwendungen
und Konstruktoren3.3.2
Kapitel 3: Eine einfache Programmiersprache
Algorithmen und Datenstrukturen I
1
Datentypen, Datentypdefinitionen
data Instrument =
|
|
|
Oboe
HonkyTonkPiano
Cello
VoiceAahs
data Musik
Note Ton Dauer
Pause Dauer
Musik :*: Musik
Musik :+: Musik
Instr Instrument Musik
Tempo GanzeZahl Musik
Algorithmen und Datenstrukturen I
=
|
|
|
|
|
2
Allgemeine Form
data T a1 . . . am
Algorithmen und Datenstrukturen I
=
C1 t11 . . . t1n1
|
...
|
Cr tr1 . . . trnr
3
Wahrheitswerte
data Bool = False | True
Algorithmen und Datenstrukturen I
-- vordefiniert
4
Wahrheitswerte
data Bool = False | True
-- vordefiniert
not :: Bool -> Bool
-- vordefiniert
Algorithmen und Datenstrukturen I
4
Wahrheitswerte
data Bool = False | True
-- vordefiniert
not :: Bool -> Bool
not True = False
not False = True
-- vordefiniert
Algorithmen und Datenstrukturen I
4
Wahrheitswerte
data Bool = False | True
-- vordefiniert
not :: Bool -> Bool
not True = False
not False = True
-- vordefiniert
(&&), (||) :: Bool -> Bool -> Bool
-- vordefiniert
Algorithmen und Datenstrukturen I
4
Wahrheitswerte
data Bool = False | True
-- vordefiniert
not :: Bool -> Bool
not True = False
not False = True
-- vordefiniert
(&&), (||) :: Bool -> Bool -> Bool
False && y = False
True && y = y
-- vordefiniert
Algorithmen und Datenstrukturen I
4
Wahrheitswerte
data Bool = False | True
-- vordefiniert
not :: Bool -> Bool
not True = False
not False = True
-- vordefiniert
(&&),
False
True
True
False
-- vordefiniert
(||)
&& y
&& y
|| y
|| y
:: Bool -> Bool -> Bool
= False
= y
= True
= y
Algorithmen und Datenstrukturen I
4
Wahrheitswerte
data Bool = False | True
-- vordefiniert
not :: Bool -> Bool
not True = False
not False = True
-- vordefiniert
(&&),
False
True
True
False
-- vordefiniert
(||)
&& y
&& y
|| y
|| y
:: Bool -> Bool -> Bool
= False
= y
= True
= y
ifThenElse :: Bool -> a -> a -> a
ifThenElse True a a’ = a
ifThenElse False a a’ = a’
Mixfix-Notation: if x >= 0 then x else -x
Algorithmen und Datenstrukturen I
4
Ganze Zahlen
data Ganz = Zero |
Succ Ganz
Zero, Succ Zero, Succ (Succ Zero), . . .
Eingebaute Datentypen: Int und Integer
Operatoren: (+), (-), (*), div, mod, (^)
Algorithmen und Datenstrukturen I
5
Tupeltypen
data Pair a b
= Pair a b
data Triple a b c = Triple a b c
Abkürzende Schreibweise: (x,y), (x,y,z)
Selektorfunktionen:
fst :: (a,b) -> a
fst (a,b) = a
-- vordefiniert
snd :: (a,b) -> b
snd (a,b) = b
-- vordefiniert
Algorithmen und Datenstrukturen I
6
Listen
data List a = Empty | Front a (List a)
Eingebaute Listen: [a] statt List a, [] statt Empty , (x:xs) statt Front x xs
Abkürzende Schreibweise: [x,y,z] statt (x:y:z:[])
Algorithmen und Datenstrukturen I
7
Funktionen auf Listen
(++) :: [a] -> [a] -> [a]
[]
++ bs = bs
(a:as) ++ bs = a:(as++bs)
head :: [a] -> a
head (a:as) = a
tail :: [a] -> [a]
tail (a:as) = as
reverse :: [a] -> [a]
reverse []
= []
reverse (a:as)= reverse as ++ [a]
Algorithmen und Datenstrukturen I
8
Der Typ Maybe
data Maybe a = Nothing | Just a
-- vordefiniert
minimum1 :: [Integer] -> Integer
minimum1 [a]
= a
minimum1 (a:as) = min a (minimum1 as)
minimum0 :: [Integer] -> Maybe Integer
minimum0 []
= Nothing
minimum0 (a:as) = Just (minimum1 (a:as))
Algorithmen und Datenstrukturen I
9
Zeichen und Zeichenketten
data Char
= ... | ’0’ | ’1’ ...
| ... | ’A’ | ’B’ ...
| ... | ’a’ | ’b’ ...
-- Pseudo-Haskell
type String = [Char]
Abkürzende Schreibweise: "Marvin" statt [’M’,’a’,’r’,’v’,’i’,’n’], "" statt
[]
isSpace :: Char -> Bool
isSpace c = c == ’ ’ || c == ’\t’ || c == ’\n’ ||
c == ’\r’ || c == ’\f’ || c == ’\v’
Algorithmen und Datenstrukturen I
10
Typsynonyme
Schon gesehen: Ton, Dauer, DNA, Protein, String
Nutzen und Gefahren:
type OrdList a = [a]
merge :: OrdList a -> OrdList a -> OrdList a
merge xs ys = xs ++ ys
Typ ok?
Algorithmen und Datenstrukturen I
11
Typsynonyme
Schon gesehen: Ton, Dauer, DNA, Protein, String
Nutzen und Gefahren:
type OrdList a = [a]
merge :: OrdList a -> OrdList a -> OrdList a
merge xs ys = xs ++ ys
Typ ok? Ja
Algorithmen und Datenstrukturen I
11
Typsynonyme
Schon gesehen: Ton, Dauer, DNA, Protein, String
Nutzen und Gefahren:
type OrdList a = [a]
merge :: OrdList a -> OrdList a -> OrdList a
merge xs ys = xs ++ ys
Typ ok? Ja
Ergebnis geordnete Liste?
Algorithmen und Datenstrukturen I
11
Typsynonyme
Schon gesehen: Ton, Dauer, DNA, Protein, String
Nutzen und Gefahren:
type OrdList a = [a]
merge :: OrdList a -> OrdList a -> OrdList a
merge xs ys = xs ++ ys
Typ ok? Ja
Ergebnis geordnete Liste? Nein
Algorithmen und Datenstrukturen I
11
Typdeklarationen, Typprüfung und Typinferenz
map f []
= []
map f (a:as) = f a : map f as
-- vordefiniert
Beobachtungen über map
Typ von map
map hat zwei Argumente.
c -> d -> e
Das Ergebnis ist eine Liste.
c -> d -> [b]
Das zweite Argument ist eine Liste.
c -> [a] -> [b]
Das erste Argument ist eine Funktion,
(f -> g) -> [a] -> [b]
die Argumente vom Typ a erhält,
(a -> g) -> [a] -> [b]
und Elemente der Ergebnisliste vom Typ b liefert.
(a -> b) -> [a] -> [b]
map :: (a -> b) -> [a] -> [b]
Algorithmen und Datenstrukturen I
12
Spezialisierungen
map :: (a -> b) -> [a] -> [b]
Spezialisierung von
Anwendung von map
a
b
map c’ [1/4, 1/8, 1/8, 1/4]
Dauer
Musik
Musik
Musik
map genCode cs
Codon
AminoAcid
map (map translate) orfs
zwei Auftreten verschiedenen Typs!
map (transponiere 5)
[cDurTonika, cDurSkala, bruderJakob]
inneres Auftreten
Codon
Protein
äußeres Auftreten
[[Codon]]
[Protein]
Algorithmen und Datenstrukturen I
13
Typklassen und Typkontexte
• Eq enthält alle Typen, deren Elemente man auf Gleichheit testen kann, und
definiert die folgenden Funktionen:
(==) :: (Eq a) => a -> a -> Bool
(/=) :: (Eq a) => a -> a -> Bool
• Ord enthält alle Typen, deren Elemente man bezüglich einer Ordnungsrelation
vergleichen kann, und definiert u.a. die folgenden Funktionen:
(<), (<=), (>=), (>) :: (Ord a) => a -> a -> Bool
max, min
:: (Ord a) => a -> a -> a
Algorithmen und Datenstrukturen I
14
• Num enthält alle numerischen Typen und definiert die grundlegenden
arithmetischen Operationen.
(+), (-), (*) :: (Num a) => a -> a -> a
negate
:: (Num a) => a -> a
Die Funktion negate entspricht dem unären Minus.
• Integral enthält die ganzzahligen Typen Int und Integer und definiert
u.a. die folgenden Funktionen:
div, mod :: (Integral a) => a -> a -> a
even, odd :: (Integral a) => a -> Bool
• Show enthält alle Typen, die eine externe Darstellung als Zeichenketten haben.
Die Funktion show liefert diese Darstellung.
show :: (Show a) => a -> String
Algorithmen und Datenstrukturen I
15
minimum1 :: [Integer] -> Integer
minimum1 [a]
= a
minimum1 (a:as) = min a (minimum1 as)
minimum :: (Ord a) => [a] -> a
minimum [a]
= a
minimum (a:as) = min a (minimum as)
-- vordefiniert
min a b = if a < b then a else b
Algorithmen und Datenstrukturen I
16
Wertdefinitionen, Variablenbindungen
theFinalAnswer :: Integer
theFinalAnswer = 42
aShortList :: [Integer]
aShortList = [1,2,3]
helloWorld :: String
helloWorld = "Hello World"
Algorithmen und Datenstrukturen I
17
theFinalAnswer’ :: Integer
theFinalAnswer’ = 6*7
aShortList’
aShortList’
helloWorld’
helloWorld’
:: [Integer]
= reverse ([3]++[2,1])
:: String
= "Hello" ++ " " ++ "World"
monotonie :: Musik
monotonie = c’ (1/1) :*: monotonie
Algorithmen und Datenstrukturen I
18
Musterbindungen
Tempo t (Instr i (m1 :+: m2 :+: m3:+: m4)) = bruderJakob
Allgemein: p = e, mit p Muster, e Ausdruck
Algorithmen und Datenstrukturen I
19
Funktionsbindungen
length :: [a] -> Int
length []
= 0
length (a:as) = 1 + length as
Algorithmen und Datenstrukturen I
-- vordefiniert
20
Allgemeiner Fall
f p11 . . . p1n
=
e1
...
=
...
f pk1 . . . pkn
=
ek
pij : Muster, ei : Ausdrücke
Algorithmen und Datenstrukturen I
21
Bewachte Gleichungen
dropSpaces :: String -> String
dropSpaces []
= []
dropSpaces (c:cs)
| isSpace c
= dropSpaces cs
| otherwise
= c : dropSpaces cs
squeeze :: String -> String
squeeze []
= []
squeeze (c:c’:cs)
| isSpace c && isSpace c’ = squeeze (c’:cs)
squeeze (c:cs)
= c : squeeze cs
Algorithmen und Datenstrukturen I
22
member :: (Ord a)
member a []
=
member a (b:bs)
| a < b
=
| a == b
=
| a > b
=
Algorithmen und Datenstrukturen I
=> a -> OrdList a -> Bool
False
False
True
member a bs
23
Gleichungen mit lokalen Definitionen
power :: (Num a, Integral b) => a -> b -> a
power x n
| n == 0
= 1
| n ‘mod‘ 2 == 0 = y
| otherwise
= y*x
where y = power (x*x) (n ‘div‘ 2)
Algorithmen und Datenstrukturen I
24
Gleichungen mit lokalen Definitionen
power :: (Num a, Integral b) => a -> b -> a
power x n
| n == 0
= 1
| n ‘mod‘ 2 == 0 = y
| otherwise
= y*x
where y = power (x*x) (n ‘div‘ 2)
pow :: (Num a) => a -> Integer -> a
pow x n
| n == 0
= 1
| otherwise = x * pow x (n-1)
Algorithmen und Datenstrukturen I
24
Gleichungen mit lokalen Definitionen
power :: (Num a, Integral b) => a -> b -> a
power x n
| n == 0
= 1
| n ‘mod‘ 2 == 0 = y
| otherwise
= y*x
where y = power (x*x) (n ‘div‘ 2)
pow :: (Num a) => a -> Integer -> a
pow x n
| n == 0
= 1
| otherwise = x * pow x (n-1)
xn = x2(n div 2)+n mod 2 = (x2 )n div 2 xn mod 2
Algorithmen und Datenstrukturen I
24
Lokale Musterbindung
splitWord :: String -> (String, String)
splitWord []
= ([],[])
splitWord (c:cs)
| isSpace c = ([], c:cs)
| otherwise = (c:w, cs’)
where (w,cs’) = splitWord cs
Algorithmen und Datenstrukturen I
25
Gültigkeits- oder Sichtbarkeitsbereiche
f :: Int -> Int
f x = f (x+x)
where x
= 1
f x = x
Algorithmen und Datenstrukturen I
-- Negativ-Beispiel
26
Gültigkeits- oder Sichtbarkeitsbereiche
f :: Int -> Int
f x = f (x+x)
where x
= 1
f x = x
-- Negativ-Beispiel
f1 :: Int -> Int
f1 x1 = f2 (x2+x2)
where x2
= 1
f2 x3 = x3
Algorithmen und Datenstrukturen I
26
Abseitsregel
• Das erste Zeichen der Definition unmittelbar nach dem where bestimmt die
Einrücktiefe des neu eröffneten Definitionsblocks.
• Zeilen, die weiter als bis zu dieser Position eingerückt sind, gelten als
Fortsetzungen einer begonnenen lokalen Definition.
• Zeilen auf gleicher Einrücktiefe beginnen eine neue Definition im lokalen Block.
• Die erste geringer eingerückte Zeile beendet den lokalen Block.
Algorithmen und Datenstrukturen I
27
Die allgemeine Form von Gleichungen
f
p11 . . . p1n
m1
pk1 . . . pkn
mk
...
f
Die pij sind beliebige Muster und die mi nehmen wahlweise eine der beiden
folgenden Formen an:
= e where { d1 ; . . . ;dp }
oder
| g1
= e1
...
| gq
= eq
where { d1 ; . . . ;dp }
Algorithmen und Datenstrukturen I
28
Das Rechnen mit Gleichungen
q :: (Num a) => a -> a
q x = 3*x^2 + 1
q 2 - 10
(Definition von q)
⇒
(3 * 2^2 + 1) - 10
⇒
(3 * 4 + 1) - 10
(Definition von (^))
⇒
(12 + 1) - 10
(Definition von (*))
⇒
13 - 10
(Definition von (+))
⇒
3
(Definition von (-))
Paßt f p1 . . . pn | g = e auf Anwendung f a1 . . . an ?
Algorithmen und Datenstrukturen I
29
Vollständige und disjunkte Muster
unique []
= []
unique [a]
= [a]
unique (a:(b:z)) = if a == b then unique (b:z)
else a : unique (b:z)
head :: [a] -> a
-- vordefiniert
head []
= error "head of empty list"
head (a:x) = a
Algorithmen und Datenstrukturen I
30
head’ :: [Integer] -> Maybe Integer
head’ []
= Nothing
head’ (a:x) = Just a
head :: [a] -> a
-- vordefiniert
head’’’ :: [a] -> Maybe a
head’’’ []
= Nothing
head’’’ (a:x) = Just a
Algorithmen und Datenstrukturen I
31
words :: String -> [String]
words xs = wds [] xs
ws :: String ->
wds "" ""
wds ws ""
wds "" (’ ’:xs)
wds "" ( x :xs)
wds ws (’ ’:xs)
wds ws ( x :xs)
Algorithmen und Datenstrukturen I
String -> [String]
= []
= [reverse ws]
= wds "" xs
= wds [x] xs
= (reverse ws) : wds "" xs
= wds (x:ws) xs
32
Bindungsstärken und Assoziativitäten
Bindungsstärke
9
8
7
6
5
4
4
3
2
1
0
Algorithmen und Datenstrukturen I
linksassoziativ
!!
nicht
assoziativ
rechtsassoziativ
.
^, ^^, **
\\
==, /=, <,
<=, >, >=,
‘elem‘,
‘notElem‘
:, ++
*, /,
‘div‘, ‘mod‘,
‘rem‘, ‘quot‘
+, -
&&
||
>>, >>=
$, ‘seq‘
33
Fallunterscheidungen
length :: [a] -> Int
length []
= 0
length (a:as) = 1 + length as
-- vordefiniert
length’ :: [a] -> Int
length’ as = case as of
[]
-> 0
a:as’ -> 1 + length’ as’
last’ :: [a] -> a
last’ as = case reverse as of a:as’ -> a
Algorithmen und Datenstrukturen I
34
Allgemeine Form von Fallunterscheidungen
case e of { p1 m1 ; . . . ;pn mn }
Die pi sind beliebige Muster und die mi nehmen wahlweise eine der beiden
folgenden Formen an:
-> e where { d1 ; . . . ;dp }
oder
| g1 -> e1
...
| gq -> eq
where { d1 ; . . . ;dp }
Algorithmen und Datenstrukturen I
35
words :: String -> [String]
-- vordefiniert
words cs = case dropSpaces cs of
[] -> []
cs’ -> w : words cs’’
where (w,cs’’) = splitWord cs’
minimum0’ :: (Ord a) => [a] -> Maybe
minimum0’ []
= Nothing
minimum0’ (a:as) = case minimum0’ as
Nothing -> Just
Just m -> Just
Algorithmen und Datenstrukturen I
a
of
a
(min a m)
36
Funktionsausdrücke
Ist n + 1 ein Wert oder eine Funktion?
Als Funktion:
f n = n + 1
\n -> n + 1
Allgemeine Form eines Funktionsausdrucks:
\p1 . . . pn -> e .
\p1 p2 -> e als Abkürzung für \p1 -> \p2 -> e
Algorithmen und Datenstrukturen I
37
Gestaffelte Funktionen
add :: Integer -> Integer -> Integer
add m n = m + n
add’ :: Integer -> (Integer -> Integer)
add’ = \m -> \n -> m + n
Algorithmen und Datenstrukturen I
38
Gestaffelte Funktionen
add :: Integer -> Integer -> Integer
add m n = m + n
add’ :: Integer -> (Integer -> Integer)
add’ = \m -> \n -> m + n
add0 :: (Integer,Integer) -> Integer
add0 (m,n) = m + n
dup :: a -> (a,a)
dup a = (a,a)
double :: Integer -> Integer
double n = add0 (dup n)
Algorithmen und Datenstrukturen I
38
note :: Int -> Int -> Dauer -> Musik
note oct h d = Note (12 * oct + h) d
note Eine Note in einer beliebigen Oktave und von beliebiger Höhe und Dauer.
note 2 Eine Note in der dritten Oktave und von beliebiger Höhe und Dauer.
note 2 ef Die Note f in der dritten Oktave und von beliebiger Dauer.
note 2 ef (1/4) ergibt Note 29 (1/4).
Algorithmen und Datenstrukturen I
39
Lokale Definitionen mit let
power’ :: (Integral b, Num a) => a -> b -> a
power’ x n = if n == 0 then 1
else let y = power’ (x*x) (n ‘div‘ 2)
in if n ‘mod‘ 2 == 0 then y
else y*x
Allgemein:
let {e1 ; . . . ; en } in e .
Algorithmen und Datenstrukturen I
40
Binärbäume
3
1
1
2
2
Algorithmen und Datenstrukturen I
3
4
41
Binärbäume
3
1
1
2
2
data Tree a = Nil
| Leaf a
| Br (Tree a) (Tree a)
Algorithmen und Datenstrukturen I
3
4
deriving Show
41
3
1
t1, t2 :: Tree Integer
2
t1 = Br (Br (Leaf 1) (Leaf 2)) (Leaf 3)
1
t2 = Br (Br (Leaf 1) Nil)
(Br (Br (Leaf 2) (Leaf 3))
(Br Nil (Leaf 4)))
2
Algorithmen und Datenstrukturen I
3
4
42
leaves
leaves
leaves
leaves
:: Tree a -> [a]
Nil
= []
(Leaf a) = [a]
(Br l r) = leaves l ++ leaves r
leftist :: [a] -> Tree a
leftist []
= Nil
leftist (a:as) = Br (leftist as) (Leaf a)
Algorithmen und Datenstrukturen I
43
leaves’
leaves’
leaves’
leaves’
leaves’
:: Tree a -> [a]
Nil
=
(Leaf a)
=
(Br Nil r)
=
(Br (Leaf a) r) =
Algorithmen und Datenstrukturen I
[]
[a]
leaves’ r
a : leaves’ r
44
leaves’
leaves’
leaves’
leaves’
leaves’
:: Tree a -> [a]
Nil
=
(Leaf a)
=
(Br Nil r)
=
(Br (Leaf a) r) =
[]
[a]
leaves’ r
a : leaves’ r
leaves’ (Br (Br l’ r’) r) = leaves’ (Br l’ (Br r’ r))
v
t
Algorithmen und Datenstrukturen I
u
=⇒
t
u
v
44
leaves’
leaves’
leaves’
leaves’
leaves’
leaves’
:: Tree a -> [a]
Nil
(Leaf a)
(Br Nil r)
(Br (Leaf a) r)
(Br (Br l’ r’) r)
=
=
=
=
=
[]
[a]
leaves’ r
a : leaves’ r
leaves’ (Br l’ (Br r’ r))
leaves’ (Br (Br (Leaf 1) (Leaf 2)) (Leaf 3))
⇒
leaves’ (Br (Leaf 1) (Br (Leaf 2) (Leaf 3)))
(Def. leaves’.5)
⇒
1 : leaves’ (Br (Leaf 2) (Leaf 3))
(Def. leaves’.4)
⇒
1 : 2 : leaves’ (Leaf 3)
(Def. leaves’.4)
⇒
1 : 2 : [3]
(Def. leaves’.2)
Algorithmen und Datenstrukturen I
45
build :: [a] -> Tree a
build [] = Nil
build [a] = Leaf a
build as = Br (build (take k as)) (build (drop k as))
where k = length as ‘div‘ 2
take :: Int -> [a] -> [a]
take n (a:as) | n > 0 = a:take (n-1) as
take _ _
= []
Algorithmen und Datenstrukturen I
46
build [1..11]:
1
2
3
6
4
5
9
7
8
10
11
11
=
5+6
=
(2 + 3) + (3 + 3)
=
((1 + 1) + (1 + 2)) + ((1 + 2) + (1 + 2))
=
((1 + 1) + (1 + (1 + 1))) + ((1 + (1 + 1)) + (1 + (1 + 1))) .
Algorithmen und Datenstrukturen I
47
build’ :: [a] -> Tree a
build’ as = fst (buildSplit (length as) as)
buildSplit :: Int -> [a] -> (Tree a, [a])
buildSplit 0 as = (Nil, as)
buildSplit 1 as = (Leaf (head as), tail as)
buildSplit n as = (Br l r, as’’)
where k
= n ‘div‘ 2
(l,as’) = buildSplit
k as
(r,as’’) = buildSplit (n-k) as’
Algorithmen und Datenstrukturen I
48
Syntaktischer Zucker / Kernsprache
• Mustergleichungen / case-Ausdrücke
length []
= 0
length (x:xs) = 1 + length xs
length’ xs = case xs of
[]
-> 0
(x:xs) -> 1 + length’ xs
• Funktionsdefinitionen / Funktions-Ausdrücke
add m n = m + n
add’ = \m -> \n -> m + n
Algorithmen und Datenstrukturen I
49
• where-Klauseln / let-Ausdrücke
double n = add0 (dup n) where
dup a = (a,a)
double n = let dup a = (a,a) in add0 (dup n)
Algorithmen und Datenstrukturen I
50
Auswertung von Fallunterscheidungen
case C e1 ...ek of {...; C x1 ...xk -> e;...}
(case-Regel)
⇒ e[x1 /e1 , . . . , xn /en ]
Algorithmen und Datenstrukturen I
51
abs :: (Ord a, Num a) => a -> a
abs n = case n >= 0 of
True -> n
False -> -n
encode :: (Num a) => Maybe a -> a
encode x = case x of
Nothing -> -1
Just n -> abs n
encode (Just 5)
⇒
case Just 5 of {Nothing -> -1; Just n -> abs n}
(Def. encode)
⇒
abs 5
(case − Regel)
⇒
case 5 >= 0 of {True -> 5; False -> -5}
(Def. abs)
⇒
case True of {True -> 5; False -> -5}
(Def. >=)
⇒
5
Algorithmen und Datenstrukturen I
(case − Regel)
52
Auswertung von Funktionsanwendungen
(\x -> e) a ⇒ e[x/a]
Algorithmen und Datenstrukturen I
(β-Regel)
(1)
53
abs
=
encode =
\n -> case n >= 0 of {True -> n; False -> -n}
\x -> case x of {Nothing -> -1; Just n -> abs n}
encode (Just 5)
(Def. encode)
⇒
(\x-> case x of {Nothing-> -1; Just n-> abs n}) (Just 5)
⇒
case Just 5 of {Nothing -> -1; Just n -> abs n}
⇒
abs 5
⇒
(\n -> case n >= 0 of {True -> n; False -> -n}) 5
(Def. abs)
⇒
case 5 >= 0 of {True -> 5; False -> -5}
(β − Regel)
⇒
case True of {True -> 5; False -> -5}
(Def. (>=))
⇒
5
Algorithmen und Datenstrukturen I
(β − Regel)
(case − Regel)
(case − Regel)
54
Auswertung von lokalen Definitionen
let {x1 = e1 ;...;xn = en } in e
⇒ e[x1 /let {x1 = e1 ;...;xn = en } in e1 , . . . ,
(let-Regel)
xn /let {x1 = e1 ;...;xn = en } in en ]
Algorithmen und Datenstrukturen I
55
rep n a = let x = a:x in take n x
rep 2 8
⇒
let x = 8:x in take 2 x
⇒
take 2 (let x = 8:x in 8:x)
(let − Regel)
⇒
take 2 (8:let x = 8:x in 8:x)
(let − Regel)
⇒
8:take 1 (let x = 8:x in 8:x)
(Def. take)
⇒
8:take 1 (8:let x = 8:x in 8:x)
(let − Regel)
⇒
8:8:take 0 (let x = 8:x in 8:x)
(Def. take)
⇒
8:8:[]
(Def. take)
Algorithmen und Datenstrukturen I
(Def. rep)
56
Herunterladen