Beispiele: Funktionsabstraktion (3) Funktionsdeklaration. Funktionsdeklaration (2) Funktionsdeklaration (3) 3. Abstraktion über Funktionsbezeichner:

Ähnliche Dokumente
Funktionales Programmieren

Beschreibung von Werten: Beschreibung von Werten: (2) Begriffsklärung: (Ausdruck, expression) (2) Begriffsklärung: (Ausdruck, expression)

Funktionales Programmieren

3. Funktionales Programmieren

Funktionales Programmieren

Software Entwicklung 1. Rekursion. Beispiel: Fibonacci-Folge I. Motivation. Annette Bieniusa / Arnd Poetzsch-Heffter

Beispiele: (Funktionen auf Listen) (3) Bemerkungen: Die Datenstrukturen der Paare (2) Die Datenstrukturen der Paare

Software Entwicklung 1

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

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

Abstraktion mittels Polymorphie und Funktionen höherer Ordnung. Abschnitt 3.3. Polymorphie und Funktionen höherer Ordnung. Unterabschnitt 3.3.

Polymorphie und Funktionen höherer Ordnung

C.3 Funktionen und Prozeduren

Gliederung. n Teil I: Einleitung und Grundbegriffe. n Teil II: Imperative und objektorientierte Programmierung

2.5 Listen. Kurzschreibweise: [42; 0; 16] Listen werden mithilfe von [] und :: konstruiert.

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

Einführung in die funktionale Programmierung

Grundlegende Datentypen

Funktionale Programmierung Grundlegende Datentypen

Software Entwicklung 1. Fallstudie: Arithmetische Ausdrücke. Rekursive Klassen. Überblick. Annette Bieniusa / Arnd Poetzsch-Heffter

Funktionale Programmierung

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

ALP I. Funktionale Programmierung

Grundlegende Datentypen

WS 2011/2012. RobertGiegerich. November 12, 2013

Software Entwicklung 1

WS 2011/2012. RobertGiegerich. November 12, 2013

Programmieren in Haskell

Vorsicht bei redundanten und unvollständigen Matches!

Vorsemesterkurs Informatik Sommersemester Aufgabenblatt Nr. 5A. Lösung zu Aufgabe 1 (Fehler in Haskell-Quelltext: Parsefehler)

Weitere Operationen auf neu deklarierten Typen: Begriffsklärung: Weitere Anwendungen der datatype-deklaration: Beispiel: (Aufzählungstypen)

Verarbeitung unendlicher Datenstrukturen Jetzt können wir z.b. die unendliche Liste aller geraden Zahlen oder aller Quadratzahlen berechnen:

Crashkurs: Haskell. Mentoring FU Berlin Felix Droop

Die Definition eines Typen kann rekursiv sein, d.h. Typ-Konstruktoren dürfen Elemente des zu definierenden Typ erhalten.

Crashkurs Haskell Mentoring WiSe 2016/17. Anja Wolffgramm Freie Universität Berlin

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

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

Gliederung. Algorithmen und Datenstrukturen I. Listen in Haskell: Listen in Haskell: Listen in Haskell. Datentyp Liste Strings Listenkomprehension

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

Funktionale Programmierung. Das Funktionale Quiz. Das Funktionale Quiz. Das Funktionale Quiz

Einführung in die Funktionale Programmierung mit Haskell

Programmieren in Haskell

Übungsblatt 6: Softwareentwicklung I (WS 2006/07)

Funktionale Programmierung Mehr funktionale Muster

Theoretische Informatik II

Datenstruktur Baum und Rekursion Software Entwicklung 1

Listen und Listenfunktionen. Grundlagen der Programmierung 2 A (Listen) Listen und Listenfunktionen. Listen? Haskell: Listen

Software Entwicklung 1

Grundlegende Datentypen

Musterlösung zur 2. Aufgabe der 4. Übung

Grundlagen der Programmierung 3 A

Workshop Einführung in die Sprache Haskell

Einführung in Haskell

Spezifikation der zulässigen Parameter. Bemerkungen: Bemerkungen: (2) Design by Contract:

Grundlagen der Programmierung 3 A

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

II.3.1 Rekursive Algorithmen - 1 -

Abstraktion (29. Mai 2006) Programmiersprachen Abstraktion. Vorletztes Mal: Speicher. Vor-vorletztes Mal: Werte. Letztes Mal: Bindung

Reelle Zahlen. Einzelzeichen. Bereiche. Aufzählungen. direkt zusammengesetzte Datentypen. einfache Datentypen: Zusammenfassung. kartesisches Produkt

Programmiersprache 1 (C++) Prof. Dr. Stefan Enderle NTA Isny

Software Entwicklung 1

Angewandte Mathematik und Programmierung

Lösungshinweise/-vorschläge zum Übungsblatt 4: Grundlagen der Programmierung (WS 2018/19)

Prof. Dr. Margarita Esponda

Grundlagen der Programmierung 2 (2.A)

Programmieren in Haskell

Die Korrektheit von Mergesort

7. Einführung in C++ Programmieren / Algorithmen und Datenstrukturen 1 Prof. Dr. Bernhard Humm FB Informatik, Hochschule Darmstadt

TECHNISCHE UNIVERSITÄT MÜNCHEN FAKULTÄT FÜR INFORMATIK

Grundlagen der Programmierung 2 A (Listen)

Gliederung. Funktionale Programmierung. Pattern matching in Haskell. Pattern matching in ERLANG. Materialien zur Vorlesung

Frage, Fragen und nochmals Fragen

Programmieren in Haskell Programmiermethodik

Funktionale Programmierung mit Haskell

Informatik I - Programmierung Globalübung Hugs98 Currying. Hugs98 Currying

Java: Eine kurze Einführung an Beispielen

Programmierung und Angewandte Mathematik

1. Typen 1.1 Typsicherheit 1.2 Typprüfung

Berechnungsschemata: Funktion als Parameter abstrahiert Operation im Schema, wird bei Aufruf des Schemas konkretisiert

3 Exkurs: Der λ-kalkül

Programm heute. Algorithmen und Datenstrukturen (für ET/IT) Definition Algorithmus. Wie beschreibt man Algorithmen?

Einführung in das λ-kalkül

Kontrollfluss. man Verzweigungen und Sprünge. o bisher linear (von oben nach unten) o Für interessante Programme braucht

Lösungen zum Übungsblatt 3: Softwareentwicklung I (WS 2006/07)

Algorithmen und Datenstrukturen (für ET/IT)

Kapitel 1: Informationsverarbeitung durch Programme

Objektorientierte Programmierung (ZQ1u2B)

3. Funktionales Programmieren 3.2 Algorithmen auf Listen und Bäumen. Heapsort verfeinert die Idee des Sortierens durch Auswahl:

Praktische Informatik 3: Funktionale Programmierung Vorlesung 2 vom : Funktionen und Datentypen

Interpreter (Hilfsfunktionen)

Zahlen in Haskell Kapitel 3

Programmierparadigmen

Programmierung WS18/19 Übungsblatt 9 (Abgabe Freitag, den um 12 Uhr)

Transkript:

Beispiele: Funktionsabstraktion (3) Funktionsdeklaration 3. Abstraktion über Funktionsbezeichner: Ausdruck: f (f x) Abstraktion: \ f x -> f (f x) Mit Bezeichnervereinbarung: twice = \ f x -> f (f x) erg = ( twice sqrt) 3.0 Äquivalente Vereinbarung: twice2 = \ f -> \ x -> f (f x) erg = ( twice sqrt) 3.0 In Haskell gibt es unterschiedliche syntaktische Formen für die Funktionsdeklaration: 1. mittels direkter Wertvereinbarung: <Funktionsbez > = <Ausdruck von Funktionstyp > fib = \ n -> if n == 0 then 0 else if n == 1 then 1 else fib (n-1) + fib (n-2) Arnd Poetzsch-Heffter TU Kaiserslautern 217 Arnd Poetzsch-Heffter TU Kaiserslautern 218 Funktionsdeklaration (2) 2. mittels einem oder mehreren formalen Parametern: <Funktionsbez > <Parameterbez1 >... = <Ausdruck > fib n = if n == 0 then 0 else if n == 1 then 1 else fib (n-1) + fib (n-2) Funktionsdeklaration (3) 3. mittels formalen Parametern und Fallunterscheidung über Wächtern: <Funktionsbez > <Parameterbez1 >... <boolscher Ausdruck > = <Ausdruck >... <boolscher Ausdruck > = <Ausdruck > Die boolschen Ausdrücke in der Deklaration heißen Wächter, engl. guards. fib n n == 0 = 0 n == 1 = 1 otherwise = fib (n-1) + fib (n-2) Das Schlüsselwort otherwise steht hier für True. Arnd Poetzsch-Heffter TU Kaiserslautern 219 Arnd Poetzsch-Heffter TU Kaiserslautern 220

Funktionsdeklaration (4) Funktionsdeklaration (5) 4. mittels Fallunterscheidung über Mustern: <Funktionsbez > <Parametermuster >... = <Ausdruck >... <Funktionsbez > <Parametermuster >... = <Ausdruck > Muster sind ein mächtiges Programmierkonstrukt, das weiter unten genauer behandelt wird. fib 0 = 0 fib 1 = 1 fib n = fib (n-1) + fib (n-2) 5. mittels Kombinationen der Formen 3 und 4. fib 0 = 0 fib n n==1 = 1 otherwise = fib (n-1) + fib (n-2) Arnd Poetzsch-Heffter TU Kaiserslautern 221 Arnd Poetzsch-Heffter TU Kaiserslautern 222 Bemerkungen: rekursive Funktionsdekl. Jeder Funktionsdeklaration sollte die Funktionssignatur vorangestellt werden und ein Kommentar, der mindestens die Voraussetzungen an die Parameter beschreibt. fib :: Integer -> Integer -- fib k verlangt: k >= 0 fib 0 = 0 fib 1 = 1 fib n = fib (n-1) + fib (n-2) Die Form einer Funktionsdeklaration sollte so gewählt werden, dass die Deklaration gut lesbar ist. 1. Einzelne rekursive Funktionsdeklaration: rpow :: Float -> Integer -> Float -- rpow r m verlangt: m >= 0 rpow r n = if n == 0 then 1.0 else r * rpow r (n-1) 2. Verschränkt rekursive Funktionsdeklaration: gerade :: Integer -> Bool ungerade :: Integer -> Bool -- Bedingung an Parameter n bei beiden Funktionen: -- n >= 0 gerade n = (n == 0) ungerade (n-1) ungerade n = if n == 0 then False else gerade (n-1) Arnd Poetzsch-Heffter TU Kaiserslautern 223 Arnd Poetzsch-Heffter TU Kaiserslautern 224

Deklaration rekursiver Funktionen Definition: (rekursive Funktionsdekl.) Begriffsklärung: (rekursive Definition) Eine Definition oder Deklaration nennt man rekursiv, wenn der definierte Begriff bzw. das deklarierte Programmelement im definierenden Teil verwendet wird. Bemerkung: Rekursive Definitionen finden sich in vielen Bereichen der Informatik und Mathematik, aber auch in anderen Wissenschaften und der nichtwissenschaftlichen Sprachwelt. Wir werden hauptsächlich rekursive Funktions- und Datentypdeklarationen betrachten. Eine Funktionsdeklaration heißt direkt rekursiv, wenn der definierende Ausdruck eine Anwendung der definierten Funktion enthält. Eine Menge von Funktionsdeklarationen heißt verschränkt rekursiv oder indirekt rekursiv (engl. mutually recursive), wenn die Deklarationen gegenseitig voneinander abhängen. Eine Funktionsdeklaration heißt rekursiv, wenn sie direkt rekursiv ist oder Element einer Menge verschränkt rekursiver Funktionsdeklarationen ist. Arnd Poetzsch-Heffter TU Kaiserslautern 225 Arnd Poetzsch-Heffter TU Kaiserslautern 226 Begriffsklärung: (rekursive Funktion) Zur Auswertung von Funktionsanwendungen: Eine Funktion heißt rekursiv, wenn es rekursive Funktionsdeklarationen gibt, mit denen sie definiert werden kann. Bemerkungen: Die Menge der rekursiven Funktionen ist berechnungsvollständig. Rekursive Funktionsdeklarationen können als eine Gleichung mit einer Variablen verstanden werden, wobei die Variable von einem Funktionstyp ist: Gesucht ist die Funktion f, die folgende Gleichung für alle n Nat erfüllt: f n = if n = 0 then 1 else n f (n 1) Sei f x = A[x] ; Eine Funktionsanwendungen f e kann nach unterschiedlichen Strategien durch Verwendung der Deklarationsgleichungen ausgewertet werden, zum Beispiel call-by-value: Werte Ausdruck e aus; Ergebnis nennt man den aktuellen Parameter z. Ersetze x in A[x] durch z. Werte den resultierenden Ausdruck A[z] aus. Haskell benutzt die Auswertungsstrategie call-by-need (siehe 3.4). Beispiele: (Rekursion) siehe Vorlesung Arnd Poetzsch-Heffter TU Kaiserslautern 227 Arnd Poetzsch-Heffter TU Kaiserslautern 228

Begriffsklärung: (lineare/repetitive Rekursion) Beispiele: Vereinfachend betrachten wir hier nur Funktionsdeklarationen, bei denen die Fallunterscheidung außen und die rekursiven Aufrufe in den Zweigen der Fallunterscheidung stehen. Eine rekursive Funktionsdeklaration heißt linear rekursiv, wenn in jedem Zweig der Fallunterscheidung höchstens eine rekursive Anwendung erfolgt ( Definition von fac). Eine rekursive Funktionsdeklaration heißt repetitiv (rekursiv), wenn sie linear rekursiv ist und die rekursiven Anwendungen in den Zweigen der Fallunterscheidung an äußerster Stelle stehen. Die übliche Definition von fac ist nicht repetitiv, da im Zweig der rekursiven Anwendung die Multiplikation an äußerster Stelle steht. Die folgende Funktion facrep ist repetitiv: facrep :: Integer -> Integer -> Integer -- facrep n res verlangt: n >= 0 && res >= 1 facrep n res = if n == 0 then res else facrep (n-1) ( res*n) fac n = facrep n 1 Arnd Poetzsch-Heffter TU Kaiserslautern 229 Arnd Poetzsch-Heffter TU Kaiserslautern 230 Begriffsklärung: (Geschachtelte Rekursion) (kaskadenartige Rekursion) Eine rekursive Funktionsdeklaration für f heißt geschachtelt rekursiv, wenn sie Teilausdrücke der Form f (... f (... )... ) enthält. Eine rekursive Funktionsdeklaration für f heißt kaskadenartig rekursiv, wenn sie Teilausdrücke der Form h(... f (... )... f (... )... ) enthält. Berechne: Wie viele Kaninchen-Pärchen leben nach n Jahren, wenn man am Anfang mit einem neu geborenden Pärchen beginnt, jedes neu geborene Pärchen nach zwei Jahren und dann jedes folgende Jahr ein weiteres Pärchen Nachwuchs erzeugt und die Kaninchen nie sterben. Arnd Poetzsch-Heffter TU Kaiserslautern 231 Arnd Poetzsch-Heffter TU Kaiserslautern 232

(kaskadenartige Rekursion) (2) Bemerkung: Die Anzahl der Pärchen stellen wir als Funktion ibo von n dar: vpr dem 1. Jahr: ibo(0) = 1 nach dem 1. Jahr: ibo(1) = 1 nach dem 2. Jahr: ibo(2) = 2 nach dem n. Jahr: die Anzahl aus dem Jahr vorher plus die Anzahl der im n. Jahr Geborenen; und die ist gleich der Anzahl vor zwei Jahren, also: ibo n = ibo(n 1) + iob(n 2) für n > 1. Insgesamt ergibt sich folgende kaskadenartige Funktionsdeklaration: ibo n = if n<=1 then 1 else ibo (n-1) + ibo (n-2) Aus Beschreibungssicht spielt die Form der Rekursion keine Rolle; wichtig ist eine möglichst am Problem orientierte Beschreibung. Aus Programmierungssicht spielt Auswertungseffizienz eine wichtige Rolle, und diese hängt von der Form der Rekursion ab. Kaskadenartige Rekursion führt im Allg. zu einer exponentiellen Anzahl von Funktionsanwendungen (z.b. bei ibo 30 bereits 1.664.079 Anwendungen). Arnd Poetzsch-Heffter TU Kaiserslautern 233 Arnd Poetzsch-Heffter TU Kaiserslautern 234 Unterabschnitt 3.1.3 Die Datenstruktur der Listen Eine Liste über einem Typ T ist eine total geordnete Multimenge mit Elementen aus T (bzw. eine Folge, d.h. eine Abb. Nat -> T ). Listen und Tupel Eine Liste heißt endlich, wenn sie nur endlich viele Elemente enthält. Haskell stellt standardmäßig eine Datenstruktur für Listen bereit, die bzgl. des Elementtyps parametrisiert ist. Typparameter werden üblicherweise geschrieben als a, b,... Arnd Poetzsch-Heffter TU Kaiserslautern 235 Arnd Poetzsch-Heffter TU Kaiserslautern 236

Die Datenstruktur der Listen (2) Die Datenstruktur der Listen (3) Typ: Funktionen: [a], a ist Typparameter (==), (/=) :: [a] [a] Bool wenn (==) auf a definiert (:) :: a [a] [a] (++) :: [a] [a] [a] head, last :: [a] a tail, init :: [a] [a] null :: [a] Bool length :: [a] Int (!!) :: [a] Int a take, drop :: Int [a] [a] Konstanten: [] :: [a] Arnd Poetzsch-Heffter TU Kaiserslautern 237 Dem Typ [a] ist als Wertemenge die Menge aller Listen über Elementen vom Typ a zugeordnet. Notation: In Haskell gibt es eine vereinfachende Notation für Listen: statt x1 : x2 :... : xn : [] kann man schreiben: [ x1, x2,..., xn ] Arnd Poetzsch-Heffter TU Kaiserslautern 238 Beispiele: (Funktionen auf Listen) Beispiele: (Funktionen auf Listen) (2) 1. Addiere alle Zahlen einer Liste von Typ [Int]: mapplus:: [Int] -> Int mapplus xl = if null xl then 0 else (head xl) + mapplus (tail xl) mapplus [1,2,3,4,5,6] 2. Prüfen einer Liste von Zahlen auf Sortiertheit: ist_sortiert :: [Int] -> Bool ist_sortiert xl = if null xl null (tail xl) then True else if ( head xl) <=( head ( tail xl)) then ist_sortiert (tail xl) else False 3. Zusammenhängen zweier Listen (engl. append): append :: [a] -> [a] -> [a] append l1 l2 = if l1 == [] then l2 else (head l1):( append (tail l1) l2) 4. Umkehren einer Liste: rev :: [a] -> [a] rev xl = if null xl then [] else append ( rev ( tail xl)) [ head xl] Arnd Poetzsch-Heffter TU Kaiserslautern 239 Arnd Poetzsch-Heffter TU Kaiserslautern 240