Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

Haskell Eine rein funktionale Sprache. Ein Rat vorweg An die anwesenden C-Programmierer: Vergesst am besten alles, was Ihr bisher über Programmierung.

Ähnliche Präsentationen


Präsentation zum Thema: "Haskell Eine rein funktionale Sprache. Ein Rat vorweg An die anwesenden C-Programmierer: Vergesst am besten alles, was Ihr bisher über Programmierung."—  Präsentation transkript:

1 Haskell Eine rein funktionale Sprache

2 Ein Rat vorweg An die anwesenden C-Programmierer: Vergesst am besten alles, was Ihr bisher über Programmierung und Programmiersprachen gelernt habt !!!

3 We now proudly present:

4 Übersicht Einführung Einführung Einordnen von Haskell in das Sprachen-Spektrum Einordnen von Haskell in das Sprachen-Spektrum imperativ vs. deklarativ imperativ vs. deklarativ Beispiel eines imperativen Programms und eines deklarativen Programms Beispiel eines imperativen Programms und eines deklarativen Programms Entwicklung der deklarativen Sprachen, insb. Haskell Entwicklung der deklarativen Sprachen, insb. Haskell l -Kalkül, Grundlage von Haskell l -Kalkül, Grundlage von Haskell Einführung, Auswertung, Erweiterung, Beispiele, … Einführung, Auswertung, Erweiterung, Beispiele, … Evolution der Programmiersprachen Evolution der Programmiersprachen Grundkonzepte funktionaler Sprachen, insb. Haskell Grundkonzepte funktionaler Sprachen, insb. Haskell Typen Typen Beispielprogramm: Kryptographie Beispielprogramm: Kryptographie Auswertung Auswertung Beispielauswertung (Tafel) Beispielauswertung (Tafel) Lazy Evaluation Lazy Evaluation Rekursive Funktionen (mit einfachen Datenstrukturen) Rekursive Funktionen (mit einfachen Datenstrukturen)

5 Das Sprachen-Spektrum Programmiersprachen imperative Programmiersprachen konventionelle Sprachen Fortran Pascal Modula C … objekt-orientierte Sprachen SmallTalk Eifel C++ Java … deklarative Programmiersprachen funktionale Sprachen Haskell LISP … Logik Sprachen Prolog … funktional-logische Sprachen Ideal Babel Curry …

6 imperativ vs. deklarativ Merkmale imperativer Sprachen 1. Die Grundidee ist die desvon Neumann bzw. desstored program Rechners. Hier werden Programme als feste Folge von Befehlen nacheinander abgearbeitet. 2. Ein Programm beschreibt, wie etwas berechnet wird. Dies geschieht als Abfolge lokaler Speichertransformationen (Wertzuweisungen). 3. Die Kontrollstruktur ist die Iteration (Schleife). Merkmaler deklarativer Sprachen 1. Die Grundidee ist das l-Kalkül von Church, eine mathematische Theorie. 2. Jede Berechnung ist das Ergebnis einer Funktion und wird durch einfache Ersetzung von Ausdrücken errechnet (Reduktion). vgl. Auswertung 3. Die Hauptkontrollstruktur ist die Rekursion.

7 WAS anstelle von WIE Somit lässt sich der Hauptunterschied zusammenfassen als Motto: Der Programmierer soll nur noch angeben, was er programmieren möchte, er soll nicht mehr damit belastet werden, wie etwas genau programmiert wird. (Aber trotzdem muss er in der Lage sein dem Computer mitzuteilen, was er haben möchte.)

8 Der Quicksortalgorithmus Vergleich zwischen imperativer und funktionaler Programmierung { public void sort(Object [] rgo) { sort(rgo, 0, rgo.length - 1); } private void sort(Object [] rgo, int nLow0, int nHigh0) { int nLow = nLow0; int nHigh = nHigh0; Object oMid; if (nHigh0 > nLow0) { oMid = rgo[ (nLow0 + nHigh0) / 2 ]; while(nLow <= nHigh) { while((nLow < nHigh0) && lessThan(rgo[nLow], oMid)) ++nLow; while((nLow0 < nHigh) && lessThan(oMid, rgo[nHigh])) --nHigh; if(nLow <= nHigh) { swap(rgo, nLow++, nHigh--); } } if(nLow0 < nHigh) sort(rgo, nLow0, nHigh); if(nLow < nHigh0) sort(rgo, nLow, nHigh0); } private void swap(Object [] rgo, int i, int j) { Object o; o = rgo[i]; rgo[i] = rgo[j]; rgo[j] = o; } protected boolean lessThan(Object oFirst, Object oSecond) { return oFirst.hashCode() < oSecond.hashCode(); } Implementierung in Java: Implementierung in Haskell: quicksort :: Ord a => [a] -> [a] quicksort [] = [] quicksort (pivot:xs) = quicksort [y | y <- xs, y<=pivot] ++ [pivot] ++ quicksort [y | y pivot]

9 Jahreszahl Theorie / Sprache Entwickler1932 l -Kalkül (siehe weiter hinten) Ursprung und gemeinsamer Kern aller funktionalen Sprachen. Churchs Intention bei der Entwicklung des l -Kalküls war eine Formalisierung des Berechenbarkeitsbegriffs auf der Basis von Funktionen Churchsche These. Diese These wurde durch die äquivalente Turing-Berechenbarkeit untermauert. Church, Kleene 1960 LISP (List Prozessing) Lisp war die erste funktionale Sprache, die von den Prinzipien der damaligen durch Fortran geprägten Programmierung abwich. Wesentliche Neuheiten von LISP waren: bedingte Ausdrücke, Verwendung von Listen als Basisstruktur, Heapverwaltung mit Garbage Collection John McCarthy 1975 ML (Meta Language) Das Bedeutendste in ML ist das mächtige polymorphe Typenkonzept, das von den meisten modernen funktionalen Sprachen adaptiert wurde. (vgl Abschnitt Typen) Milner, Gordon, University of Edinburgh 1980Hope In Hope wurden zum ersten Mal benutzerdefinierte Datenstrukturen und Pattern Matching bei der Definition von Funktionen über solchen Strukturen zugelassen. R. Burstall, D. MacQueen, D. Sannella, Uni. of Edinburgh

10 Jahreszahl Theorie / Sprache Entwickler1985Miranda Eine der wenigen kommerziell vertriebenen funktionalen Sprachen. Besonders ist hier der Einsatz von Funktionalen (Funktionen höherer Ordnung), sowie die bedarfsgesteuerte Auswertungsstrategie lazy evaluation D. Turner, University of Kent ~1988 Haskell ( Vorname des Logikers Haskell Brooks Curry ) Haskell ist nach dem amerikanischen Logiker Haskell Brooks Curry benannt (weil Haskell [die Sprache] curryfizierte Funktionen liebt, wie Haskell [der Logiker] Haskell wurde von einem Komitee von Forschern entwickelt, die das Ziel verfolgten eine rein funktionale Programmiersprache einzuführen. Haskell unterstützt eine enrome Vielfalt von (auch oben aufgeführten) Konzepten und zeichnet sich insbesondere durch ein mächtiges Typsystem und eine saubere Modellierung von interaktiven Ein-/Ausgaben aus. Bemerkenswert ist, dass eine vollständige formale Semantikdefinition (http://haskell.org/report/index.html) existiert. Ziele beim Entwurf von Haskell waren: Für Lehre, Forschung und Anwendungen, insbesondere für Programmierung großer Systeme Für Lehre, Forschung und Anwendungen, insbesondere für Programmierung großer Systeme Vollständige Beschreibung von Syntax und Semantik Vollständige Beschreibung von Syntax und Semantik Frei erhältlich Frei erhältlich Basiert auf allgemein akzeptierten Ideen Basiert auf allgemein akzeptierten Ideen Komitee unter Leitung von P.Hudak (Yale University), Ph. Wadler (Glasgow University) Logiker H. B. Curry

11 Entwicklung Zur Geschichte: 1988 Gründung des Haskell-Komitees (auf der FPCA), dem u.a. Paul Hudak, Simon Peyton Jones und Philip Wadler angehören Haskell 1.0 Sprachdefinition 1992 Haskell 1.2 Sprachdefinition 1996 Haskell 1.3 Sprachdefinition 1997 Haskell 1.4 Sprachdefinition 1999 Haskell 98 Sprachdefinition

12 l - Das Lambda-Kalkül Das Lambda-Kalkül besteht aus zwei Bausteinen Funktionsabstraktion l x.A definiert eine (anonyme) Funktion, die ein x bekommt, und einen Ausdruck A als Funktionskörper hat (in dem in der Regel x vorkommt, aber nicht vorkommen muß) Funktionsabstraktion l x.A definiert eine (anonyme) Funktion, die ein x bekommt, und einen Ausdruck A als Funktionskörper hat (in dem in der Regel x vorkommt, aber nicht vorkommen muß) Funktionsapplikation FA bedeutet, daß die Funktion F auf dem Ausdruck A angewandt wird Funktionsapplikation FA bedeutet, daß die Funktion F auf dem Ausdruck A angewandt wird Die Groß- u. Kleinschreibung dient nur der Übersicht, es gibt keinen Grund Funktionen und Variablen zu unterscheiden, denn es kommt auf den Kontext an.

13 Beispiele für Funktionen (1) Die Identität: l x.x Die Identität: l x.x Eine Funktion, die jedes Argument auf die Identitätsfunktion abbildet: l y.( l x.x) Eine Funktion, die jedes Argument auf die Identitätsfunktion abbildet: l y.( l x.x) Die Identität, angewandt auf sich selbst: ( l x.x)( l y.y) ( l y.y) Die Identität, angewandt auf sich selbst: ( l x.x)( l y.y) ( l y.y)

14 Beispiele für Funktionen (2) Nicht alle Variablennamen müssen definiert sein, auch die folgenden sind korrekte l -Terme l x.Fx ( l y.y)(z) ? uv l k.Jm Nicht alle Variablennamen müssen definiert sein, auch die folgenden sind korrekte l -Terme l x.Fx ( l y.y)(z) ? uv l k.Jm

15 Beispiele für Funktionen (3) Ein komplexerer Ausdruck ( l f.( l x.f(fx)))uv ( l x.u(ux))v ( l x.u(ux))v u(uv) u(uv) Diese Funktion wendet also eine Funktion zweimal auf ein Argument an.

16 Eigenschaften des l -Kalküls Als Bausteine gibt es nur Funktionsabstraktionen und -applikationen. Das ist alles! Es gibt keine Zahlen, Funktionsnamen, arithmetische Funktionen, Wahrheitswerte Als Bausteine gibt es nur Funktionsabstraktionen und -applikationen. Das ist alles! Es gibt keine Zahlen, Funktionsnamen, arithmetische Funktionen, Wahrheitswerte Die Funktionen werden nicht benannt, sie sind anonym. (Alle heißen l ) Die Funktionen werden nicht benannt, sie sind anonym. (Alle heißen l ) Das Lambda-Kalkül ist ungetypt Das Lambda-Kalkül ist ungetypt

17 Kalkül Definition Ein Kalkül besteht aus zwei wesentlichen Teilen: Der Kalkülsprache, d.h. Der Kalkülsprache, d.h. einem zugrunde liegenden Alphabet von Zeichen einem zugrunde liegenden Alphabet von Zeichen einer Definition der wohlgeformten Ausdrücke einer Definition der wohlgeformten Ausdrücke Dem Deduktionsgerüst, d.h. Dem Deduktionsgerüst, d.h. Axiomen aus der Menge der wohlgeformten Ausdrücke (Terme) Axiomen aus der Menge der wohlgeformten Ausdrücke (Terme) Ableitungsregeln, mit denen Ausdrücke umgeformt/ausgewertet werden Ableitungsregeln, mit denen Ausdrücke umgeformt/ausgewertet werden nach K.Schröter(1941)

18 kurzer weiterer Ausblick Auf den ersten Blick bietet das l -Kalkül nur sehr primitive Funktionen, die nicht von praktischem Nutzen sind. Auf den ersten Blick bietet das l -Kalkül nur sehr primitive Funktionen, die nicht von praktischem Nutzen sind. Man kann allerdings mit dem l -Kalkül Fallunterscheidungen, Zahlen und arithmetische Funktionen herleiten Man kann allerdings mit dem l -Kalkül Fallunterscheidungen, Zahlen und arithmetische Funktionen herleiten

19 kurz notiert(1) Um Zahlen zu erhalten, werden wir jetzt ganz bestimmte Funktionen mit den natürlichen Zahlen identifizieren: F n A (n-malige Anwendung von F auf A) entspricht der induktiven Definition F 0 A:=A F n+1 A:= F( F n A) Die Zahlen z 0,z 1,… werden dann definiert durch: z n := l fx.f n (x) Um Zahlen zu erhalten, werden wir jetzt ganz bestimmte Funktionen mit den natürlichen Zahlen identifizieren: F n A (n-malige Anwendung von F auf A) entspricht der induktiven Definition F 0 A:=A F n+1 A:= F( F n A) Die Zahlen z 0,z 1,… werden dann definiert durch: z n := l fx.f n (x)

20 kurz notiert(2) Definition von Plus: für zwei Zahlen z und z Definition von Plus: für zwei Zahlen z und z l zzfx.zf(zfx) Definition von Mal l zzfx.z(zf)x Definition von Mal l zzfx.z(zf)x

21 Beispiel zur Addition (verkürzt) Beispiel: Plus z 2 z 3 z 5 z 2 = z 2 =(λ f x. f (f (x))) z 3 = (λ f x. f (f (f (x)))) Plusz 2 z 3 (λ z z f x. z f (z f x)) z 2 z 3 (λ z f x. z 2 f (z f x)) z 3 (λ z f x. f ( f (z f x))) z 3 (λ f x. f ( f (z3 f x))) (λ f x. f ( f ( f ( f ( f (x)))))) ( = z5 )

22 Beispiel zur Addition (ausgeschrieben) Am Beispiel: Plus z 2 z 3 ( z 5 ) Plus z 2 z 3 (λ z z f x. z f (z f x)) (λ g y. g (g (y))) (λ g y. g ( g ( g (y)))) (λ z f x. (λ g y. g (g (y))) f (z f x)) (λ g y. g ( g ( g (y)))) (λ z f x. (λ y. f ( f (y)) (z f x)) (λ g y. g ( g ( g (y)))) (λ z f x. f ( f (z f x))) (λ g y. g ( g ( g (y)))) (λ z f x. f ( f (λ g y. g ( g ( g (y))) f x))) (λ f x. f ( f (λ y. f ( f ( f (y))) x))) (λ f x. f ( f ( f ( f ( f (x)))))) ( = z5 )

23 kurz notiert(3) Es ist außerdem möglich If-Anweisungen mit dem l -Kalkül auszudrücken. Sei True := l xy.x (Projektion auf das erste Argument) Sei False := l xy.y (Projektion auf das zweite Argument) Es ist außerdem möglich If-Anweisungen mit dem l -Kalkül auszudrücken. Sei True := l xy.x (Projektion auf das erste Argument) Sei False := l xy.y (Projektion auf das zweite Argument) Damit können wir ein If definieren: If.. then.. else.. entspricht hier: l bxy.bxy wobei b entweder True oder False ist. Damit können wir ein If definieren: If.. then.. else.. entspricht hier: l bxy.bxy wobei b entweder True oder False ist.

24 Resultat aus der Theoretischen Informatik Das l -Kalkül ist logisch äquivalent zu der Turing- Maschine. Somit kann man mit dem l -Kalkül (zumindest theoretisch) genau die Probleme lösen (ausrechnen), die die heutigen Computer auch lösen können. Jede von einem Computer berechenbare Funktion ist auch im Lambda-Kalkül berechenbar.

25 Evolution der Programmiersprachen high level PShigh level PS Assembler Maschinensprache Problemspezifikation Programm Rechner vertical migration

26

27 Grundkonzepte funktionaler Sprachen, insb. Haskell Die meisten Anwendungsprobleme sind auf natürliche Weise als Funktionen definiert, Bsp.: Die meisten Anwendungsprobleme sind auf natürliche Weise als Funktionen definiert, Bsp.: sin x, exp, … sin x, exp, … LATEX: LATEX: Datenbanksysteme (SQL): Datenbanksysteme (SQL): EVA-Prinzip EVA-Prinzip f 1 f 1 Eingaben Ausgabe f n f n Funktion

28 Grundkonzept Haskell Auch Haskell arbeitet so: Ein funktionales Programm ist eine Menge von Funktionsdefinitionen f 1 X 1.. X n = e 1 … f r X 1,r.. X n,r = e r Funktionsbezeichner Parametervariablen Rumpfausdruck Eine Funktion transformiert Eingabe in Ausgabe

29 Beispiele in Haskell -- hier stehen Kommentare -- einfache arithmetische Funktionen add x1 x2 = x1 + x2 square x = x * x negate x = -x -- Konstantendefinitionen e = newline = '\n' -- Test auf Identität: Vergleichoperatoren allEqual n m p = (n==m) && (m==p) -- Maximumsfunktion: Bsp. für Fallunterscheidung max a b | a>b = a | a==b = a | a==b = a | otherwise = b | otherwise = b

30 Typen In Haskell haben alle Datenobjekte einen wohldefinierten Typ. Ein Typ ist eine Menge von Objekten gleicher Art, z.B. existieren Basistypen wie Int = Menge aller ganzen Zahlen (32 Bit) Integer = Menge beliebiger ganzer Zahlen, insb. nur durch den Speicher beschränkte große Zahlen Bool = {True, False} Char = Menge aller Zeichen String = Eine Liste von Char Neben diesen Basistypen gibt es auch Funktionstypen, wie z.B.: Int Int = Menge aller einstelligen Funktionen über den ganzen Zahlen (wie z.B.: Quadrieren): Int Int Int = Menge aller zweistelligen Funktionen über den ganzen Zahlen (wie z.B.: Addieren): In Haskell- Programmen können optional Typdeklarationen der Form name :: type zu Definitionen angegeben werden. Bei der Compilation von Programmen erfolgt eine automatische Typinferenz und Typüberprüfung (type checker). Nur korrekt typisierbare Programme können somit compiliert werden. Hierdurch werden viele Programmfehler frühzeitig erkannt. Ist keine konkrete Typisierung vorgenommen, so bestimmt der Compiler automatisch den allgemeinsten Typ für jedes Datenobjekt.

31 Beispiele in Haskell -- hier stehen Kommentare -- einfache arithmetische Funktionen add :: Int -> Int -> Int add x1 x2 = x1 + x2 square :: Int -> Int square x = x * x negate :: Int -> Int negate x = -x -- Konstantendefinitionen e :: Double e = newline :: Char newline = '\n' -- Test auf Identität allEqual :: Int -> Int -> Int -> Bool allEqual n m p = (n==m) && (m==p) -- Maximumsfunktion? Fallunterscheidung max :: Double -> Double -> Double max a b | a>b = a | a==b = a-- bedingte Auswertungen, funktioniert wie | a==b = a-- bedingte Auswertungen, funktioniert wie | otherwise = b-- eine if/case-Struktur, das erste passende wird | otherwise = b-- eine if/case-Struktur, das erste passende wird -- ausgewertet.

32 Typen Bei der Compilation von Programmen erfolgt eine automatische Typinferenz und Typüberprüfung (type checker). Nicht typisierte Programme werden automatisch möglichst allgemein typisiert. Bei der Compilation von Programmen erfolgt eine automatische Typinferenz und Typüberprüfung (type checker). Nicht typisierte Programme werden automatisch möglichst allgemein typisiert. Ist ein Programm im Hugs-System geladen, kann man mit : t d ie Typdeklaration eines Objekts erfahren. z.B.:

33 Beispielprogramm Kryptographie (1) Als Beispielprogramm betrachten wir das Caesar- Verschlüsselungsverfahren. Als Beispielprogramm betrachten wir das Caesar- Verschlüsselungsverfahren. Hierzu stellt man sich das Alphabet (im einfachen Fall nur die kleinen Buchstaben) im Kreis angeordnet vor. Hierzu stellt man sich das Alphabet (im einfachen Fall nur die kleinen Buchstaben) im Kreis angeordnet vor. Ordnet man den Zeichen von a bis z die Nummern 0 bis 25 zu, so ist das Verschieben innerhalb des Kreises eine Addition modulo 26. Ordnet man den Zeichen von a bis z die Nummern 0 bis 25 zu, so ist das Verschieben innerhalb des Kreises eine Addition modulo 26. Die Verschlüsselung besteht darin, anstelle jedes Klartextbuchstabens das Zeichen auszugeben, das im Kreis um eine festgelegte Anzahl von Positionen später kommt. Die Verschlüsselung besteht darin, anstelle jedes Klartextbuchstabens das Zeichen auszugeben, das im Kreis um eine festgelegte Anzahl von Positionen später kommt.

34 Beispielprogramm Kryptographie (2) Somit ergibt sich die Funktion schiebe : Somit ergibt sich die Funktion schiebe : Als nächstes müssen wir zwei Übergangsfunktionen zwischen den Zahlen und den Zeichen definieren Als nächstes müssen wir zwei Übergangsfunktionen zwischen den Zahlen und den Zeichen definieren schiebe :: Int -> Int -> Int schiebe schluessel zahl = mod (zahl + schluessel) 26 position :: Char -> Int position zeichen = (ord zeichen) - 97 buchstabe :: Int -> Char buchstabe zahl = chr (zahl + 97)

35 Beispielprogramm Kryptographie (3) Als nächstes definieren wir eine Funktion caesar:: Int -> Char -> Char die mit einem Schlüssel ein Zeichen verschlüsselt. Dazu verwenden wir die vorigen Funktionen. Als nächstes definieren wir eine Funktion caesar:: Int -> Char -> Char die mit einem Schlüssel ein Zeichen verschlüsselt. Dazu verwenden wir die vorigen Funktionen. caesar :: Int -> Char -> Char caesar schluessel zeichen = buchstabe (schiebe schluessel (position zeichen))

36 Die Verschlüsselung eines ganzen Wortes erfordert die zeichenweise Anwendung dieser Funktion auf die Buchstaben des Wortes. Hierzu lässt sich die Funktion map verwenden, mit der eine Funktion elementweise auf eine Zeichenkette angewendet werden kann. Die Verschlüsselung eines ganzen Wortes erfordert die zeichenweise Anwendung dieser Funktion auf die Buchstaben des Wortes. Hierzu lässt sich die Funktion map verwenden, mit der eine Funktion elementweise auf eine Zeichenkette angewendet werden kann. Eckige Klammern um den Typ Char signalisieren, dass es sich um eine Liste von Char handelt (also um einen String). Eckige Klammern um den Typ Char signalisieren, dass es sich um eine Liste von Char handelt (also um einen String). Beispielprogramm Kryptographie (4) caesar_wort :: Int -> [Char] -> [Char] caesar_wort schluessel wort = map (caesar schluessel) wort Bemerkenswert ist hier die Tatsache das caesar schluessel als eine einstellige Funktion betrachtet wird (Da der Erste von den beiden Parametervariablen bereits fest dasteht).

37 Beispielprogramm Kryptographie (5)

38 Auswertung Bei der Auswertung von Ausdrücken werden die Funktionsdefinitionen als Ersetzungsregeln interpretiert. Bei der Auswertung von Ausdrücken werden die Funktionsdefinitionen als Ersetzungsregeln interpretiert. In einem Reduktionsschritt wird eine Funktionsapplikation durch den Rumpf der entsprechenden Funktionsdefinitionen ersetzt. Dabei wird eine Substitution der Parameter vorgenommen. In einem Reduktionsschritt wird eine Funktionsapplikation durch den Rumpf der entsprechenden Funktionsdefinitionen ersetzt. Dabei wird eine Substitution der Parameter vorgenommen. Ein Ausdruck ohne reduzierbare Teilausdrücke heißt Normalform. Die Normalform eines Ausdrucks ist somit das Resultat seiner Auswertung. Ein Ausdruck ohne reduzierbare Teilausdrücke heißt Normalform. Die Normalform eines Ausdrucks ist somit das Resultat seiner Auswertung.

39 Verschiedene Auswertungsstrategien Haskell verwendet eine Form der Left-most outermost Strategie Haskell verwendet eine Form der Left-most outermost Strategie Auf dieser Strategie baut die bedarfsgesteuerte Auswertungsstrategie auf (engl. lazy evaluation, call by need) Auf dieser Strategie baut die bedarfsgesteuerte Auswertungsstrategie auf (engl. lazy evaluation, call by need) Das Motto von Lazy Evaluation lautet: Das Motto von Lazy Evaluation lautet: Berechne einen Ausdruck bzw. einen Teilausdruck nur, wenn es unbedingt nötig ist und dann auch nur einmal.

40 Rekursive Funktionen Rekursion ist eine selbst-referenzierende Art der Definition. Rekursion ist eine selbst-referenzierende Art der Definition. Von Rekursion spricht man, wenn in der Definition einer Funktion auf die Funktion selbst Bezug genommen wird. Von Rekursion spricht man, wenn in der Definition einer Funktion auf die Funktion selbst Bezug genommen wird. Grundidee: Meistens Divide and Conquer Prinzip Grundidee: Meistens Divide and Conquer Prinzip Wir zerlegen das Problem in zwei Fälle: Wir zerlegen das Problem in zwei Fälle: Einen leichten Fall, den wir lösen Einen leichten Fall, den wir lösen Und einen schweren Fall, den wir auf das leichte Problem zurückführen Und einen schweren Fall, den wir auf das leichte Problem zurückführen

41 Beispiele zur Rekursion Rekursion kommt häufig in der Mathematik und in der Informatik vor, z.B.: Rekursion kommt häufig in der Mathematik und in der Informatik vor, z.B.: Die Fakultätsfunktion: n! Die Fakultätsfunktion: n! Fibonacci-Zahlen: fib 0 =0 fib 1 =1 fib n =fib n-1 +fib n-2 Fibonacci-Zahlen: fib 0 =0 fib 1 =1 fib n =fib n-1 +fib n-2 Übung: Programmieren Sie diese beiden Funktionen mit ihrem Tischnachbarn auf Papier und werten Sie einen nichttrivialen Beispielausdruck dazu aus. Übung: Programmieren Sie diese beiden Funktionen mit ihrem Tischnachbarn auf Papier und werten Sie einen nichttrivialen Beispielausdruck dazu aus.

42 weiterführende Beispiele für Rekursion in Haskell Durch das Grundprinzip der deklarativen Sprachen in Kombination mit der Rekursion lassen sich somit leicht mathematische Strukturen auf den Computer übertragen. Durch das Grundprinzip der deklarativen Sprachen in Kombination mit der Rekursion lassen sich somit leicht mathematische Strukturen auf den Computer übertragen. Als Beispiel kann man einen Baum nennen. Dieser lässt sich in Haskell rel. einfach als neue Datenstruktur anlegen und man kann sehr einfach auf ihm operieren. Als Beispiel kann man einen Baum nennen. Dieser lässt sich in Haskell rel. einfach als neue Datenstruktur anlegen und man kann sehr einfach auf ihm operieren. Einfache Beispiele sind z.B. folgende Geometrische Formen Einfache Beispiele sind z.B. folgende Geometrische Formen

43 Beispiele Hugs verfügt auch über eine grafische Ausgabe. Mit ihr kann man relativ leicht solche Strukturen erzeugen.

44 Etwas komplexere fraktale Strukturen Mit etwas mehr Rechen- power und Mathematik ist es dann auch möglich beliebige komplexe Strukturen zu erzeugen. Weiteres Material (Tutorials, Papers, …) sowie den Compiler findet man unter © by Christian Heil


Herunterladen ppt "Haskell Eine rein funktionale Sprache. Ein Rat vorweg An die anwesenden C-Programmierer: Vergesst am besten alles, was Ihr bisher über Programmierung."

Ähnliche Präsentationen


Google-Anzeigen