Programmierparadigmen

Werbung
Unendliche Listen
Unendliche Listen
Gliederung
Programmierparadigmen
1
Unendliche Listen
Verknüpfen mit zipWith
Filtern
D. Rösner
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Institut für Wissens- und Sprachverarbeitung
Fakultät für Informatik
Otto-von-Guericke Universität Magdeburg
c
Sommer 2011, 26. April 2011, 2011
D.Rösner
D. Rösner PGP 2011 . . .
Unendliche Listen
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
D. Rösner PGP 2011 . . .
1
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
Unendliche Listen
2
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
‘lazy evaluation’ (auf Deutsch: verzögerte Auswertung):
schrittweise Expansion der Definition von ones
Werte werden nur bestimmt, wenn sie auch tatsächlich
benötigt werden
ones = 1:ones
= 1:(1:ones)
= 1:(1:(1:ones))
...
da in Haskell grundsätzlich ‘lazy’ evaluiert wird, werden für
unendliche Listen in Haskell keine zusätzlichen
Sprachmittel benötigt
Beispiel:
damit zum Beispiel:
Main> head ones
1
Main> head (tail ones)
1
Main> take 10 ones
[1,1,1,1,1,1,1,1,1,1]
ones = 1:ones
Wie ist diese Definition zu lesen?
s.a. [Tho99], 17.6
D. Rösner PGP 2011 . . .
-- Def.
-- Def.
-- Def.
4
D. Rösner PGP 2011 . . .
5
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
Welche Listenfunktionen können bei unendlichen Listen
angewendet werden?
alle Listenfunktionen, bei denen Werte in endlich vielen
Auswertungsschritten gewonnen werden können, lassen
sich wegen Haskells verzögerter Auswertung auf
unendliche Listen anwenden
dazu gehören auch die meisten Funktionen höherer
Ordnung
z.B. map, filter, zipWith, . . .
Welche Funktionen höherer Ordnung gehören nicht dazu?
Welche Listenfunktionen können bei unendlichen Listen
angewendet werden?
fast alle!
ausgenommen sind nur solche Listenfunktionen, bei denen
die Berechnung eines Werts das Durchlaufen der ganzen
(endlichen) Liste erfordert
dazu gehören:
........................................
........................................
.....................................
.....................................
.....................................
......................................
D. Rösner PGP 2011 . . .
Unendliche Listen
7
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
D. Rösner PGP 2011 . . .
Unendliche Listen
Unendliche Listen
9
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
durch elementweises Verknüpfen lässt sich folgendes
definieren
Beispiel: unendliche Liste der natürlichen Zahlen
Erinnerung: paarweises Verknüpfen korrespondierender
Elemente zweier Listen
integers = 1: (zipWith (+) ones integers)
zipWith :: (a->b->c) -> [a]->[b]->[c]
zipWith z (a:as) (b:bs)
= z a b : zipWith z as bs
zipWith _ _
= []
_
Wie ist diese Definition zu lesen?
Zugriff auf einen endlichen Abschnitt:
Main> take 10 integers
[1,2,3,4,5,6,7,8,9,10]
D. Rösner PGP 2011 . . .
10
D. Rösner PGP 2011 . . .
11
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
schrittweise Expansion der Definition von integers
Beispiel: unendliche Liste der Quadratzahlen
integers = 1: (zipWith (+) ones integers)
ones:
1 1 1 1 ...
squares = map (\ x -> x*x) integers
Zugriffe:
integers:
ones:
1
1
1
integers:
ones:
1
1
2
1
1
1 ...
integers:
ones:
1
1
2
1
3
1
1
-- zipWith: (+) 1 2
1 ...
integers:
...
1
2
3
4
-- zipWith: (+) 1 3
1
1 ...
Main> take 20 squares
[1,4,9,16,25,36,49,64,81,100,121,144,
169,196,225,256,289,324,361,400]
-- zipWith: (+) 1 1
D. Rösner PGP 2011 . . .
Unendliche Listen
Main> head (filter (> 100000) squares)
100489
D. Rösner PGP 2011 . . .
12
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
Unendliche Listen
13
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
Beispiel: unendliche Liste der Kubikzahlen
Variante 1:
Beispiel: unendliche Liste der Werte der Fakultätsfunktion
faks = 1: (zipWith (*) faks (tail integers))
Main> take 10 faks
[1,2,6,24,120,720,5040,40320,362880,3628800]
cubes = map (\ x -> x*x*x) integers
Variante 2:
Damit auch möglich:
cubes’ = (zipWith (*) squares integers)
fak n = faks!!(n-1)
Zugriff:
Anwendung:
Main> take 10 cubes
[1,8,27,64,125,216,343,512,729,1000]
Main> fak 3
6
Main> fak 10
3628800
Main> head (filter (> 1000000) cubes)
1030301
D. Rösner PGP 2011 . . .
14
D. Rösner PGP 2011 . . .
15
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
Beispiel: unendliche Liste der Fibonacci-Zahlen
Filtern erzeugt unendliche Listen, deren Elemente eine
gewünschte Eigenschaft haben
Beispiel: unendliche Liste der nicht durch 7 teilbaren
Zahlen
fibgen a b = a:(fibgen b (a + b))
fibs = fibgen 0 1
Zugriffe:
divisiblep x y = mod x y == 0
no_sevens
= filter (\x -> not (divisiblep x 7)) [1 ..]
Main> take 10 fibs
[0,1,1,2,3,5,8,13,21,34]
Main> take 5 (filter (>10000) fibs)
[10946,17711,28657,46368,75025]
D. Rösner PGP 2011 . . .
Unendliche Listen
16
D. Rösner PGP 2011 . . .
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
Unendliche Listen
17
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
mögliche Verwendung: Kalender
Beispiel: unendliche Liste der Wochentage
Main> zipWith (showTag "Januar 2010")
(drop 4 wochentage) [1 .. 31]
data Wochentag = Mo | Di | Mi | Do | Fr | Sa | So
deriving (Eq, Ord, Enum, Show, Read)
liefert
["Fr 1. Januar 2010","Sa 2. Januar 2010","So 3. Januar 2010",
"Mo 4. Januar 2010","Di 5. Januar 2010","Mi 6. Januar 2010",
"Do 7. Januar 2010","Fr 8. Januar 2010","Sa 9. Januar 2010",
"So 10. Januar 2010","Mo 11. Januar 2010","Di 12. Januar 2010",
"Mi 13. Januar 2010","Do 14. Januar 2010","Fr 15. Januar 2010",
"Sa 16. Januar 2010","So 17. Januar 2010","Mo 18. Januar 2010",
"Di 19. Januar 2010","Mi 20. Januar 2010","Do 21. Januar 2010",
"Fr 22. Januar 2010","Sa 23. Januar 2010","So 24. Januar 2010",
"Mo 25. Januar 2010","Di 26. Januar 2010","Mi 27. Januar 2010",
"Do 28. Januar 2010","Fr 29. Januar 2010","Sa 30. Januar 2010",
"So 31. Januar 2010"]
wochentage = [Mo ..] ++ wochentage
Main> take 30 wochentage
[Mo,Di,Mi,Do,Fr,Sa,So,Mo,Di,Mi,Do,Fr,Sa,
So,Mo,Di,Mi,Do,Fr,Sa,So,Mo,Di,Mi,Do,Fr,Sa,
So,Mo,Di]
D. Rösner PGP 2011 . . .
19
D. Rösner PGP 2011 . . .
20
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
Hilfsfunktion:
showTag
unendliche Listen lassen sich oft auch als
Listenkomprehension schreiben
Beispiel: unendliche Liste aller pythagoräischen Tripel
showTag monat
= (\ d n -> shows d
(showChar ’ ’
(shows n
(showChar ’.’
(showChar ’ ’ monat)))))
Erinnerung: pythagoräische Tripel sind Tripel (x, y , z)
ganzer Zahlen, für die gilt:
x 2 + y 2 = z2
in Haskell (s.a. [Tho99], 17.6):
Beispiel für Verwendung:
pythagTriples =
[(x,y,z)| z <- [2 .. ], y <- [2 .. z-1],
x <- [2 .. y-1], x*x + y*y == z*z]
Main> showTag "Februar 2009" Di 3
"Di 3. Februar 2009"
D. Rösner PGP 2011 . . .
Unendliche Listen
21
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
Ausgabe einer solchen unendlichen Liste muss
abgebrochen werden:
Main> pythagTriples
[(3,4,5),(6,8,10),(5,12,13),(9,12,15),(8,15,17),(12,16,20),
(15,20,25),(7,24,25),(10,24,26),(20,21,29),(18,24,30),
(16,30,34),(21,28,35),(12,35,37),(15,36,39),(24,32,40),
(9,40,41),(27,36,45),(30,40,50),(14,48,50),(24,45,51),
(20,48,52),(28,45,53),(33,44,55),(40,42,58),(36,48,60),
(11,60,61),(39,52,65),(33,56,65),(25,60,65),(16,63,65),
(32,60,68),(42,56,70),(48,55,73),(24,70,74),(45,60,75),
(21,72,75),(30,72,78),(48,64,80),(18,80,82),(51,68,85),
(40,75,85),(36,77,85),(13,84,85),(60,63,87),(39,80,89),
(54,72,90),(35,84,91),(57,76,95),(65,72,97),(60,80,100),
(28,96,100),(20,99,101),(48,90,102),(40,96,104),(63,84,105),
(56,90,106),(60,91,109),(66,88,110),(36,105,111),(15,112,113),
(69,92,115),(80,84,116),(45,108,117),(56,105,119),(72,96,120),
(22,120,122),(27,120,123),(75,100,125),(44,117,125),(35,120,125),
(78,104,130),(66,112,130),(50,120,130),(32,126,130),(81,108,135),
D. Rösner PGP 2011 . . .
24
(64,120,136),(88,105,137),(84,112,140),(55,132,143),(100,105,145),
(87,116,145),(24,143,145),(17,144,145),(96,110,146),(48,140,148),
D. Rösner PGP 2011 . . .
Unendliche Listen
23
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
Frage: kleinstes pythagoräisches Tripel, bei dem alle
Zahlen grösser als 1000?
Main> head (filter (\(x,_,_) -> x > 1000)
pythagTriples )
liefert (Warnung: Zeitbedarf):
(1020,1071,1479)
D. Rösner PGP 2011 . . .
25
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
aus Prelude.hs:
die unendliche Liste der Potenzen einer natürlichen Zahl
Variante 1: Listenkomprehension
iterate
:: (a -> a) -> a -> [a]
powers n = [n^x| x <- [0 ..]]
iterate f x
Variante 2: mit iterate
= x : iterate f (f x)
Welche unendliche Liste wird durch iterate f x
erzeugt?
powers’ n = iterate (*n) 1
..................................................
D. Rösner PGP 2011 . . .
Unendliche Listen
27
D. Rösner PGP 2011 . . .
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
Unendliche Listen
28
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Zufallszahlen
für viele Anwendungen (z.B. Simulationen) werden
Zufallszahlen benötigt
ein gängiges Verfahren zur Erzegung von
Pseudo-Zufallszahlen (engl. pseudo-random numbers) ist
die sog. lineare Kongruenzmethode (s.a. [Tho99], 17.6):
Variante 3:
powers’’ n = 1:map (*n) (powers’’ n)
Was ist der Vorteil von Variante 3?
..................................................
D. Rösner PGP 2011 . . .
29
ausgehend von einem ganzzahligen Startwert (engl. seed)
werden aufeinanderfolgende Werte der Folge von
ganzzahligen Pseudo-Zufallszahlen dadurch berechnet,
dass
der jeweils aktuelle Wert mit einem Multiplikator
multipliziert,
dann zum Produkt ein Inkrement addiert und schliesslich
der Folgewert durch Bestimmung des Rests modulo einer
festen Zahl (dem sog. Modulus) gewonnen wird
D. Rösner PGP 2011 . . .
31
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
Zufallszahlen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Zufallszahlen
über ’günstige’ Werte für die Grössen Multiplikator,
Inkrement und Modulus gibt es Erfahrungswissen
eine mögliche Wertbelegung (s.a. [Tho99], 17.6):
in Haskell:
seed
multiplier
increment
modulus
nextRand n
= (multiplier*n + increment) ‘mod‘ modulus
randomSequence = iterate nextRand
Unendliche Listen
17489
25173
13849
65536
mögliche Nutzung:
Konsequenz: die Werte der Pseudo-Zufallsfolge liegen
zwischen 0 und modulus-1
D. Rösner PGP 2011 . . .
=
=
=
=
Main> take 10 (randomSequence seed)
[17489,59134,9327,52468,43805,8378,18395,59344,
52777,23478]
32
D. Rösner PGP 2011 . . .
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
Zufallszahlen
33
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Zufallszahlen
aus gleichverteilten Zufallszahlen im Bereich zwischen 0
und modulus-1 lassen sich durch Skalierung solche in
einem interessierenden Zahlenbereich gewinnen
z.B. Simulation von Lottozahlen:
z.B. Simulation eines Würfels:
Main> take 30 (scaleSequence 1 49
(randomSequence seed))
[14,45,7,40,33,7,14,45,40,18,17,15,5,23,18,
46,11,26,31,4,5,46,35,10,44,14,19,3,2,21]
Main> take 30 (scaleSequence 1 6
(randomSequence seed))
[2,6,1,5,5,1,2,6,5,3,3,2,1,3,3,6,2,4,4,1,
1,6,5,2,6,2,3,1,1,3]
D. Rösner PGP 2011 . . .
34
D. Rösner PGP 2011 . . .
35
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
Zufallszahlen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Zufallszahlen
in Haskell:
bei der Skalierung auf Werte zwischen from und to (je
einschliesslich) wird der Bereich zwischen 0 und
Modulus-1 in to - from + 1 gleichgrosse Abschnitte
zerlegt
scaleSequence from to
= map scale
where
scale n = from + n ‘div‘ denom
range = to - from + 1
denom = modulus ‘div‘ range
Zahlen aus dem jeweiligen Abschnitt wird dann der
korrespondierende Wert aus dem Bereich von from bis to
zugeordnet
D. Rösner PGP 2011 . . .
Unendliche Listen
36
D. Rösner PGP 2011 . . .
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
Zufallszahlen
37
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Zufallszahlen
Beispiel: Zufallsfolgen von Zeichen
Bereich [’a’ ..’z’]
gleichverteilte Zufallsfolgen für endliche Listen mit Werten
anderer Datentypen lassen sich ebenfalls leicht gewinnen
Skalierung für eine Liste von möglichen Werten:
Main> take 30 (uniformFrom [’a’ ..’z’])
"gxdurdhxujihcljyfnqccxsfxgkbak"
uniformFrom list
= map (\n -> list!!(fromIntegral n))
(scaleSequence 0
(toInteger ((length list) - 1))
(randomSequence seed))
D. Rösner PGP 2011 . . .
38
Bereich [’a’ ..’e’]
Main> take 30 (uniformFrom [’a’ ..’e’])
"beaedabeebbbacbebcdaaedbebbaac"
D. Rösner PGP 2011 . . .
39
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
Beispiel: Sieb des Eratosthenes
Beispiel: Sieb des Eratosthenes
Definition als Haskell-Funktion:
benannt nach Eratosthenes von Kyrene (ca. 276 v.Chr. –
194 v.Chr.), dem griechischen Mathematiker, Geograph,
Geschichtsschreiber, Philologe und Dichter sowie Direktor
der Bibliothek von Alexandria.
sieve [] = []
sieve (x:xs)
= x:(sieve (filter (\y -> not (divisiblep y x)) xs))
Idee:
Alternative Definition:
a Streiche in der Liste aller natürlichen Zahlen alle Vielfachen
der gerade als Primzahl erkannten Zahl.
b Die erste der dann verbleibenden Zahlen ist wiederum prim.
c Wiederhole a.
D. Rösner PGP 2011 . . .
Unendliche Listen
sieve (x:xs)
= x:(sieve (filter (\y -> mod y x /= 0) xs))
41
D. Rösner PGP 2011 . . .
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
Unendliche Listen
42
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
Beispiel: unendliche Liste der Primzahlen
die ersten 100
Beispiel: unendliche Liste der Primzahlen
Main> take 100 primes
[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,
83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,
167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,
257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,
353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,
449,457,461,463,467,479,487,491,499,503,509,521,523,541]
primes = sieve [2 ..]
D. Rösner PGP 2011 . . .
43
D. Rösner PGP 2011 . . .
44
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
Unendliche Listen
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Unendliche Listen
Beispiel: unendliche Liste der Primzahlen
naheliegende Abstraktion: das beim Sieben
anzuwendende Prädikat wird zusätzliches Argument
m.a.W.:
die erste Primzahl grösser als eine Schranke
sievep _ [] = []
Main> head (filter (> 1000) primes)
1009
Main> head (filter (> 10000) primes)
10007
Main> head (filter (> 5000) primes)
5003
sievep p (x:xs)
= x:(sievep p (filter (\y -> p y x) xs))
der Spezialfall des Sieb des Eratosthenes ergibt sich dann
als
primes’
= sievep (\a b -> mod a b /= 0) [2 ..]
D. Rösner PGP 2011 . . .
Unendliche Listen
45
Einführung
Funktionen
... höherer Ordnung
Datentypen
Listenkomprehension
Iterierte Funktionsanwendung
Zufallszahlen
Sieben
Literatur: I
Simon Thompson.
Haskell - The Craft of Functional Programming.
Addison Wesley Longman Ltd., Essex, 1999.
2nd edition, ISBN 0-201-34275-8; Accompanying Web site:
http://www.cs.ukc.ac.uk/people/staff/sjt/craft2e.
D. Rösner PGP 2011 . . .
47
D. Rösner PGP 2011 . . .
46
Herunterladen