Effizienz in Haskell

Ähnliche Dokumente
Master-Veranstaltung Funktionale Programmierung. Effizienz. Wintersemester 2007/2008 Kim Kirchbach (Inf6310) Mirco Schenkel (Inf6311)

Algorithmen und Datenstrukturen 1 Kapitel 5

4.1 Bäume, Datenstrukturen und Algorithmen. Zunächst führen wir Graphen ein. Die einfachste Vorstellung ist, dass ein Graph gegeben ist als

Prof. Dr. Margarita Esponda

Übung Algorithmen und Datenstrukturen

Programmierung 1 - Repetitorium

Komplexität von Algorithmen OOPM, Ralf Lämmel

Informatik I Komplexität von Algorithmen

HASKELL KAPITEL 2.1. Notationen: Currying und das Lambda-Kalkül

Algorithmen und Datenstrukturen Effizienz und Funktionenklassen

WS 2012/2013. Robert Giegerich. 21. November 2012

A6.1 Logarithmus. Algorithmen und Datenstrukturen. Algorithmen und Datenstrukturen. A6.1 Logarithmus. A6.2 Landau-Notation. A6.

Stand der Vorlesung Komplexität von Algorithmen (Kapitel 3)

Funktionale Programmierung ALP I. Funktionen höherer Ordnung SS Prof. Dr. Margarita Esponda. Prof. Dr. Margarita Esponda

Agenda. 1 Einleitung. 2 Binäre Bäume. 3 Binäre Suchbäume. 4 Rose Trees. 5 Zusammenfassung & Ausblick. Haskell Bäume. Einleitung.

Algorithmen und Datenstrukturen (ESE) Entwurf, Analyse und Umsetzung von Algorithmen (IEMS) WS 2012 / 2013 Vorlesung 3, Donnerstag 7.

( )= c+t(n-1) n>1. Stand der Vorlesung Komplexität von Algorithmen (Kapitel 3)

Abschnitt 7: Komplexität von imperativen Programmen

Funktionale Programmierung ALP I. Funktionen höherer Ordnung. Teil 2 SS Prof. Dr. Margarita Esponda. Prof. Dr.

Übung Algorithmen und Datenstrukturen

Datenstrukturen: Mathematische Grundlagen. 26. Juli / 27

Funktionale Programmierung ALP I. Die Natur rekursiver Funktionen SS Prof. Dr. Margarita Esponda. Prof. Dr.

V. Claus, Juli 2005 Einführung in die Informatik II 45

3.3 Laufzeit von Programmen

Komplexität eines Algorithmus, Grössenordnung, Landau-Symbole, Beispiel einer Komplexitätsberechnung (Mergesort) 7. KOMPLEXITÄT

Grundlagen der Programmierung 2. Bäume

WS 2009/10. Diskrete Strukturen

WS 2011/2012. Robert Giegerich Dezember 2013

Algorithmus Analyse. Johann Basnakowski

Grundlagen der Programmierung 2 (1.B)

HASKELL KAPITEL 8. Bäume

Kapitel 9. Komplexität von Algorithmen und Sortieralgorithmen

Kapitel 10. Komplexität von Algorithmen und Sortieralgorithmen

Komplexität von Algorithmen:

ALP I Induktion und Rekursion

Algorithmenbegriff: Berechenbarkeit. Algorithmenanalyse. (Berechnung der Komplexität)

ALP I. Funktionale Programmierung

2. Effizienz von Algorithmen

2. Grundlagen. Beschreibung von Algorithmen durch Pseudocode. Korrektheit von Algorithmen durch Invarianten.

Kapitel 9. Komplexität von Algorithmen und Sortieralgorithmen

Informatik-Seminar Thema 6: Bäume

WS 2013/2014. Robert Giegerich. 11. Dezember 2013

WS 2011/2012. Georg Sauthoff November 2011

Kapitel 6. Komplexität von Algorithmen. Xiaoyi Jiang Informatik I Grundlagen der Programmierung

Algorithmen und Datenstrukturen (ESE) Entwurf, Analyse und Umsetzung von Algorithmen (IEMS) WS 2014 / 2015 Vorlesung 3, Donnerstag 6.

WS 2013/2014. Robert Giegerich. 11. Dezember 2013

ProInformatik: Funktionale Programmierung. Punkte

Komplexität von Algorithmen

Übung Algorithmen und Datenstrukturen

Programmieren und Problemlösen

Ordnungsrelationen auf Mengen

Komplexität. G. Zachmann Clausthal University, Germany Leistungsverhalten von Algorithmen

Programmieren in Haskell Programmiermethodik

Zunächst ein paar einfache "Rechen"-Regeln: Lemma, Teil 1: Für beliebige Funktionen f und g gilt:

Programmierung 1 (Wintersemester 2012/13) Lösungsblatt 10 (Kapitel 11)

Praktische Informatik 3: Funktionale Programmierung Vorlesung 6 vom : Funktionen Höherer Ordnung II und Effizienzaspekte

VL-04: Rekursionsgleichungen. (Datenstrukturen und Algorithmen, SS 2017) Gerhard Woeginger

Übung Algorithmen und Datenstrukturen

AlgoDat Fragen zu Vorlesung und Klausur

Objektorientierte Programmierung VL: Prof. Dr. Marco Block-Berlitz - Freie Universität Berlin Proinformatik III

Einführung in die funktionale Programmierung

Algorithmen und Datenstrukturen

Grundlagen der Programmierung 2 (1.B)

Übersicht. Datenstrukturen und Algorithmen. Laufzeit von Algorithmen. Übersicht. Vorlesung 2: Asymptotische Effizienz (K3) Begründung Grenzwerte

Haskell, Typen, und Typberechnung. Grundlagen der Programmierung 3 A. Einige andere Programmiersprachen. Typisierung in Haskell

Sortieren II / HeapSort Heaps

Datenstrukturen. Mariano Zelke. Sommersemester 2012

Programmieren in Haskell. Stefan Janssen. Strukturelle Rekursion. Universität Bielefeld AG Praktische Informatik. 10.

Was bisher geschah. deklarative Programmierung. funktionale Programmierung (Haskell):

Komplexität von Algorithmen

Übung Algorithmen und Datenstrukturen

Prof. Dr. Margarita Esponda

2 Wachstumsverhalten von Funktionen

Babeș-Bolyai Universität Cluj Napoca Fakultät für Mathematik und Informatik Grundlagen der Programmierung MLG5005. Rekursion

Klausur Programmierung WS 2002/03

Algorithmen und Datenstrukturen I Grundlagen

Algorithmen und Programmieren 1 Funktionale Programmierung - Musterlösung zur Übungsklausur -

Kostenmodell. Daniel Graf, Tobias Pröger. 22. September 2016 (aktualisierte Fassung 5 vom 9. Oktober 2016)

Vorlesung Algorithmische Geometrie. Streckenschnitte. Martin Nöllenburg INSTITUT FÜR THEORETISCHE INFORMATIK FAKULTÄT FÜR INFORMATIK

f 1 (n) = log(n) + n 2 n 5 f 2 (n) = n 3 + n 2 f 3 (n) = log(n 2 ) f 4 (n) = n n f 5 (n) = (log(n)) 2

1. Musterlösung. Problem 1: Average-case-Laufzeit vs. Worst-case-Laufzeit ** i=1

Einführung in Haskell

8. A & D - Heapsort. Werden sehen, wie wir durch geschicktes Organsieren von Daten effiziente Algorithmen entwerfen können.

Ziele. Kapitel 10: Komplexität von Algorithmen und Sortierverfahren. Beispiel: Lineare Suche eines Elements in einem Array (1)

Informatik II, SS 2016

Lösung Probeklausur Informatik I

Datenstrukturen & Algorithmen

Datenstrukturen und Algorithmen. Christian Sohler FG Algorithmen & Komplexität

Grundlagen der Programmierung 3 A

Einführung in die Informatik I

Klausur Algorithmen und Datenstrukturen

14. Sortieren II Heapsort. Heapsort. [Max-]Heap 7. Heapsort, Quicksort, Mergesort. Binärer Baum mit folgenden Eigenschaften

Heapsort / 1 A[1] A[2] A[3] A[4] A[5] A[6] A[7] A[8]

Effiziente Algorithmen I

Haskell, Typen, und Typberechnung. Grundlagen der Programmierung 3 A. Überladung und Konversion in Haskell. Typisierung in Haskell

Laufzeitanalyse (1) demogr.

Transkript:

Informatikseminar WS03/04 Oliver Lohmann mi4430 1 Gliederung Allgemeine Definition von Effizienz Lazy Evaluation Asymptotische Analyse Parameter Akkumulation Tupling Speicherplatz kontrollieren

Allgemeine Definition von Effizienz Definition Effizienz "Verhältnis zwischen dem erzielten Ergebnis und den eingesetzten Mitteln " (ISO 9000:000) Nicht zu verwechseln mit der Defintion von Effektivität: "Ausmaß, in dem geplante Tätigkeiten verwirklicht und geplante Ergebnisse erreicht werden" (ISO 9000:0000) 3 Gliederung Allgemeine Definition von Effizienz Lazy Evaluation Asymptotische Analyse Parameter Akkumulation Tupling Speicherplatz kontrollieren 4

Lazy Evaluation Beispiel zu Auswertungsschemata I Innerste Reduktion innermost reduction square (3+4) = {definition of +} square (7) = {definition of square} 7 7 = {definition of } 49 Äußerste Reduktion outermost reduction square (3+4) = {definition of square} (3+4) (3+4) = {definition of +} 7 (3+4) = {definition of +} 7 7 = {definition of } 49 5 Lazy Evaluation Beispiel zu Auswertungsschemata II Innerste Reduktion innermost reduction fst (square 4,square ) = {definition of square} fst(4 4, square ) = {definition of } fst(16, square ) = {definition of square} fst(16, ) = {definition of } fst(16,4) = {definition of fst} 16 Äußerste Reduktion outermost reduction fst(square 4,square ) = {definition of fst} square 4 = {definition of square} 4 4 = {definition of } 16 6

Lazy Evaluation Äußerste-/Innerste Reduktion Äußerste Reduktion terminiert häufiger Wenn sie terminieren, liefern beide Strategien das gleiche Ergebnis Vorteil Äußerste Reduktion: Falls eine Normalform vorhanden ist, kann sie berechnet werden Äußerste Reduktion wird auch Normale Ordnung (normal order) bezeichnet Nachteil Äußerste Reduktion: Gleiche Ausdrücke in Reduktionen müssen wiederholt berechnet werden (Bsp. I) Lösung: Graphen 7 Lazy Evaluation Graphen Bäume wurden definiert als eine Menge von durch Kanten miteinander verbundenen Knoten, wobei die Kanten gerichtet von der Wurzel zu den Blättern verlaufen. Zusätzlich durfte jeder Knoten nur maximal einen Vorgängerknoten besitzen (spezielle Form der Graphen) Bei Graphen entfallen diese Einschränkungen: ein Graph besteht aus Knoten, die durch Kanten verbunden sind. Die Kanten können dabei entweder gerichtet oder ungerichtet sein. 8

Lazy Evaluation Graphen Entspricht: (3+4) (3+4) Äußerste Graphen Reduktion outermost graph reduction square (3+4) = {definition of square} = {definition of +} = {definition of } 49 Nur drei Reduktionsschritte! 9 Lazy Evaluation Graphen Geteilte Ausdrücke sind ebenfalls in lokalen Definitionen zu finden: roots a b c = ((-b-d)/e,(-b+d)/e) where d = sqrt (square b-4 a c) e = a Der erste Reduktionsschritt für roots 1 5 3 10

Lazy Evaluation Effizienz Lazy Evaluation geg.: eine Reduktionsfolge e 0 e 1 e e n Zeitbedarf für Reduktion: n+ ε, ε entspricht dem Zeitaufwand der Reduktions-Suche Es wird die Zeit vernachlässigt, die zur Suche des Ausdrucks benötigt wird der den Ansprüchen einer äußersten Reduktion genügt. Bei großen Ausdrücken ein gewichtiger Faktor. Platzbedarf für Reduktion: Größe des größten Ausdrucks (Speicherplatz wird durch Garbage Collection wiederholt genutzt) 11 Lazy Evaluation Zusammenfassung Lazy Evaluation wird in Haskell eingeführt, weil Reduktionen terminieren, wenn es eine Reduktionsfolge gibt die terminiert die Eager Evaluation genau so viele oder mehr Schritte benötigt um zu terminieren Ausdrücke werden in Haskell grundsätzlich nicht strikt ausgewertet! 1

Gliederung Allgemeine Definition von Effizienz Lazy Evaluation Asymptotische Analyse Parameter Akkumulation Tupling Speicherplatz kontrollieren 13 Asymptotische Analyse Komplexität Zeitkomplexität (time complexity) Wie viel Laufzeit benötigt ein Programm? Raumkomplexität (space complexity) Wie viel Speicherplatz benötigt ein Programm? Die Komplexität eines Algorithmus oder einer Funktion bezeichnet die Wachstumsrate von Resourcen wie zum Beispiel der Laufzeit gegenüber der Menge der zu verabeitenden Daten. 14

Asymptotische Analyse Ordnung (order notation) Mathematisches Verfahren zur Einordnung von Funktionen: geg.: zwei Funktionen f, g eine positive Konstante C eine natürliche Zahl n 0 Hinweis: Funktionsresultate nur für große n aussagekräftig. 1. O-Notation (big O-notation) f hat höchstens den Grad g: f = O(g), wenn gilt: f(n) C g(n) für alle n n 0 15 Asymptotische Analyse Ordnung (order notation). Ω-Notation (big Omega-notation) n 0 f hat mindestens den Grad g: f = Ω(g), wenn gilt: f(n) C g(n) für alle n Führt man beide Regeln zusammen, erhält man ein drittes Kriterium: 3. Θ-Notation (big Theta-notation) f hat exakt den Grad g: 16

Asymptotische Analyse Anmerkungen order-notation = nicht im herkömmlichen Sinne, eher ist enthalten in O, Ω, Θ definieren Mengen. Diese Mengen enthalten alle Funktionen für die eine Konstante C existiert und die die Ungleichung für O, Ω oder Θ erfüllen. Häufig anzutreffen: O(1) = Ω (1) = Θ(1), konstantes Wachstum (Array-Zugriff) O(lg n ), logarithmisches Wachstum (binäres Suchen) O(n), lineares Wachstum (Zugriff auf alle Elemente einer Liste) O(n log n ), n-faches logarithmisches Wachstum (heap-sort) O(n k ), polynomisches Wachstum (quadratisch, selection-sort) O( n ), exponentielles Wachstum 17 Asymptotische Analyse Hinweise O( n) beschreibt das Verhalten einer anonymen Funktion O( n) + O( n) = O( n), da f1( n) + f( n) = O( n) f Ein Ausdruck wie O(1 ) + O( N n= 1 ) +... + O( N O( n ) ) bedeutet nicht : Statt dessen referenziert O( n die den Anprüchen N n= 1 f ( n) N n= 1 O( n f ( n) = O( n ) = O( N 3 ) ) eine einzelne Funktion ) genügt. f, 18

Asymptotische Analyse Beispielrechnung geg.: eine Liste eine Funktion append, fügt Elemente hinten an die Liste an Berechnung: Ein Element anhängen: O(n), Liste mit n-elementen traversieren n Elemente anhängen: 1 + + 3 + n-1 + n, entspricht: n i= 1 i n n + 1) = = ( n + n = O( n ) 19 Asymptotische Analyse Zeitkomplexität Notation: T(f)(n) Drei wichtige Hinweise: 1. Auf die Notation der Speicherplatzkomplexität wird erst im weiteren Verlauf genauer eingegangen, hier noch nicht formal korrekt.. T(f)(n) ist stets eine worst-case Einschätzung. 3. Die Eager Evaluation wird als Auswertungsgrundlage genutzt. 0

Asymptotische Analyse Warum Eager Evaluation? Unter Eager Evaluation kann die Laufzeitanalyse kompositionell betrachtet werden Es gilt weiterhin: theoretische obere Grenzen für Eager & Lazy Evaluation identisch häufig: untere Grenzen für Eager & Lazy Evaluation ebenfalls identisch 1 Asymptotische Analyse Beispiel reverse reverse1 [] = [] reverse1 (x : xs) = reverse1 xs ++ [x] reverse = foldl prefix [] where prefix xs x = x : xs Zur Erinnerung: (++) :: [α] [α] [α] [] ++ ys = ys (x:xs) ++ ys = x : (xs ++ ys)

Asymptotische Analyse Analyse reverse1 T(reverse1)(0) T(reverse1)(n+1) = O(1) = Θ(1) = T(reverse1)(n) + T(++)(n,1) Aussage. Gleichung: Um eine Liste der Länge n+1 umzudrehen, dreht man eine Liste der Länge n um und konkateniert es mit einer Liste der Länge 1. Rekursion für T(reverse1) lösen und Einsatz der Gleichung: T(++)(n,m) = Θ(n) T ( reverse1)( n) = n i= 0 Θ( n) = Θ( n ) 3 Asymptotische Analyse Analyse reverse Vorbereitende Maßnahme: foldl eliminieren, um direkte Rekursion zu erhalten reverse = foldl prefix [] where prefix xs x = x : xs umformen, Hilfsfunktion definieren: reverse xs accum ws[] accum ws (x:xs) = accum [] xs = ws = accum (x:ws) xs 4

Asymptotische Analyse Analyse reverse accum nimmt zwei Argumente auf Länge der Argumente: m, n T(accum)(m,0) T(accum)(m,n+1) = O(1) = Θ(1) = O(1) + T(accum)(m,n) T(reverse) = Θ(n) 5 Gliederung Allgemeine Definition von Effizienz Lazy Evaluation Asymptotische Analyse Parameter Akkumulation Tupling Speicherplatz kontrollieren 6

Parameter Akkumulation Idee Durch Hinzufügen eines weiteren Parameters Laufzeit verbessern Häufig genutzte Technik um teure ++-Operationen zu vermeiden 7 Parameter Akkumulation Beispiel flatten Bekannt: flatten :: Btree a [a] [a] flatten (Leaf x) = [x] flatten (Fork xt yt)= flatten xt ++ flatten yt Neue Definition: flatcat :: Btree a [a] [a] flatcat xt xs = flatten xt ++ xs Es gilt: flatten xt = flatcat xt []! Rekursive Struktur für flatcat: flatcat flatcat (Leaf x) xs flatcat (Fork xt yt) xs :: Btree a [a] [a] = x : xs = flatcat xt (flatcat yt xs) 8

Parameter Akkumulation Laufzeitanalyse zum Glätten eines perfekten binären Baums flatten T(flatten)(0) = O(1) T(flatten)(h+1) = T(flatten)(h) + T(++)( h, h ) Aus Induktion folgt: T(flatten)(h) = Θ(h h ) flatten benötigt also O(s log s) Schritte auf einem Baum der Größe s. flatcat T(flatcat)(0,n) = O(1) T(flatten)(h+1,n) = O(1) + T(flatcat)(h, h +n) + T(flatcat)(h,n) Aus Induktion folgt: T(flatcat)(h,n) = Θ( h ) flatcat benötigt also lineare Laufzeit im Verhältnis zur Baumgröße. 9 Gliederung Allgemeine Definition von Effizienz Lazy Evaluation Asymptotische Analyse Parameter Akkumulation Tupling Speicherplatz kontrollieren 30

Tupling Idee Ein weiteres Ergebnis in Funktionen mitführen Umsetzung über Ergebnistupel, z.b.: statt: fib :: Integer Integer besser: fibtwo :: Integer (Integer,Integer) 31 Tupling Beispiel fib Bekannt: fib 0 = 0 fib 1 = 1 fib (n+) = fib n + fib(n+1) Laufzeitanalyse für fib T(fib)(0) = O(1) T(fib)(1) = O(1) T(fib)(n+) = T(fib)(n) + T(fib)(n+1) + O(1) Aus Induktion folgt: T(fib)(n) = Θ(fib n), benötigte Zeit ist also proportional zur Größe des Ergebnisses. fib n = Θ(Φ n ), mit Φ = (1+sqrt(5))/ (Goldener Schnitt) exakt : fib( n) = 1 1+ 5 5 n = 1 5 Φ n 3

Tupling Beispiel fib fibtwo n = (fib n, fib(n+1)) Direkte Rekursion: fibtwo 0 = (0,1) fibtwo (n+1) = (b,a+b) where (a,b) = fibtwo n T(fib) = Θ(n), lineare Laufzeit Steigerung der Effizienz von exponentiell zu linear! 33 Tupling Beispiel average -- berechnet den Durchschnitt einer Float-Liste average :: [Float] Float average xs = (sum xs) / (length xs) Zwei Traversierungen nötig -- berechnet Summe und Länge einer (Float-)Liste sumlen xs = (sum xs, length xs) Direkte Rekursion: sumlen [x] sumlen (x:y:xs) = (x,1) = (x+z,n+1) where (z,n) = sumlen(y:xs) -- berechnet den Durchschnitt einer Float-Liste average = uncurry(/). sumlen Eine Traversierung nötig 34

Tupling Anmerkungen zu average Beide Funktionen haben eine Laufzeit Θ(n) Der Zeitgewinn durch die einmalige Traversierung, könnte durch die Bildung von Ergebnistupeln wieder verloren gehen Warum also average??? Speicherplatz sparen! 35 Tupling Speicherplatz einsparen mit average average [1..1000] da average xs zweimal auf der rechten Seite xs referenziert, wird der doppelte Speicherplatz benötigt Mit der zweiten Definition von average erreichen wir eine konstante Belegung des Speichers 36

Gliederung Allgemeine Definition von Effizienz Lazy Evaluation Asymptotische Analyse Parameter Akkumulation Tupling Speicherplatz kontrollieren 37 Speicherplatz kontrollieren Reduktionen & Speicherplatz Reduktionsfolge sum [1..1000] mit sum = foldl (+) 0 sum [1..1000] = foldl (+) 0 [1..1000] = foldl (+) (0+1) [..1000] = foldl (+) ((0+1)+) [3..1000] : : = foldl (+) ( ((0+1)+)+ +1000)[] = ( ((0+1)+)+ +1000) = 500500 Die Berechnung von sum [1..n] mit outermost reduction wächst proportional zur Größe von n 38

Speicherplatz kontrollieren Neue Reduktionsstrategie sum [1..1000] = foldl (+) 0 [1..1000] = foldl (+) (0+1) [..1000] = foldl (+) 1 [..1000] = foldl (+) (1+) [3..1000] = foldl (+) 3 [3..1000] : : = foldl (+) 500500 [] = 500500 Mischung aus innermost & outermost reduction Neue Funktion Definieren, die Kontrolle über Reduktion erlaubt 39 Speicherplatz kontrollieren strict Funktion strict f x = if x = then else f x Kontrolliert die Reduktionsfolge ein Term strict f e, reduziert e auf Kopf Normal-Form (λ- Ausdruck) Jeder Ausdruck in Normal Form ist auch in Kopf Normal-Form, aber nicht umgekehrt (Normal Form kann nicht mehr reduziert werden) 40

Speicherplatz kontrollieren Idee: foldl als strict definieren -- keine HUGS kompatible Notation sfoldl ( ) a [] = a Sfoldl ( ) a (x:xs)= strict (sfoldl ( )) (a x) xs Mit sum = sfoldl(+) 0, entsteht eine neue Reduktionsfolge: sum[1..1000] = sfoldl (+) 0 [1..1000] = strict (sfoldl(+))(0+1) [..1000] = sfoldl (+) 1 [..1000] = strict (sfoldl(+))(1+) [3..1000] = sfoldl (+) 3 [3..1000] : : = sfoldl (+) 500500 [] = 500500 41 Speicherplatz kontrollieren Verbindung mit average herstellen average = uncurry (/). Sumlen sumlen = sfoldl f (0,0) where f (s,n) x = (s+x, n+1) Erhalten Es entsteht wir folgende ein Programm Reduktionsfolge: mit konstanter Speicherplatznutzung? sumlen [1..1000] = sfoldl f (0,0) [1..1000] = strict (sfoldl f) (0+1,0+1) [..1000] Nein, = sfoldl da die f (0+1,0+1) Hilfsfunktion [..1000] f nicht strikt ist. = strict (sfoldl f) ((0+1)+,(0+1)+1) [3..1000] = 4

Speicherplatz kontrollieren Lösung average Problem f muss ebenfalls strikt definiert sein f (s,n) x = strict (strict tuple (s+x))(n+1) where tuple a b = (a,b) Mit f, entsteht die Reduktionsfolge: sum[1..1000] = sfoldl f (0,0) [1..1000] = strict (sfoldl f ) (strict(strict tuple(0+1))(0+1)) [..1000] = strict (sfoldl f ) (strict(strict tuple(0+1))1) [..1000] = strict (sfoldl f ) (strict(strict tuple 1)1) [..1000] = strict (sfoldl f ) (1,1) [..1000] = sfoldl f (1,1) [..1000] 43 Speicherplatz kontrollieren Anmerkungen zu fold wenn ( ) assoziativ zu der Identität e ist, dann gilt: foldr ( ) e xs = foldl ( ) e xs, für alle endlichen Listen xs Es bestehen Unterschiede in der Komplexität! Daumenregel : Wenn ( ) nicht strikt ist, dann ist foldr häufig effizienter! Beispiele: and und ++. 44

Ende. 45