Deklarative Programmierung
|
|
- Hella Giese
- vor 6 Jahren
- Abrufe
Transkript
1 Deklarative Programmierung Prof. Dr. Sibylle Schwarz HTWK Leipzig, Fakultät IMN Gustav-Freytag-Str. 42a, Leipzig Zimmer Z 411 (Zuse-Bau) sibylle.schwarz@htwk-leipzig.de Sommersemester 2015
2 Motivation... there are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult. Tony Hoare, 1980 ACM Turing Award Lecture
3 Programmierparadigmen Abstraktionsstufen (zeitliche Entwicklung): Programm = Maschinencode menschenlesbare symbolische Darstellung (Assembler) Beschreibung von Programmablauf- und Datenstrukturen (imperative und objektorientierte Sprachen) Beschreibung der Aufgabenstellung (deklarative Sprachen, z.b. funktional, logisch, Constraints) Unterschied besteht darin, wie detailliert das Programm das Lösungsverfahren beschreiben muss.
4 Formen der deklarativen Programmierung Grundidee: Jedes Programm ist ein mathematisches Objekt mit einer bekannten wohldefinierten Semantik funktionale Programmierung (z.b. Haskell, ML, Lisp): Programm: Menge von Funktions-Definitionen (Gleichungen zwischen Termen) Ausführung: Pattern matching, Reduktion (Termersetzung) logische Programmierung (Prolog): Programm: Menge logischer Formeln (Horn-Klauseln) Ausführung: Unifikation, SLD-Resolution funktional-logische Programmierung (z.b. Mercury, Curry): Kombination funktionaler und logischer Konzepte Constraint-Programmierung: Programm: Menge von Constraints (z.b. Gleichungen, Ungleichungen, logische Formeln) Ausführung: Constraint-Löser (abhängig vom Constraint-Bereich) Beispiele: Constraints: Menge linearer Gleichungen Constraint-Löser: Gauß-Algorithmus Constraints: aussagenlogische CNF Constraint-Löser: SAT-Solver
5 Beispiele funktionale Programmierung: foldr (+) 0 [1,2,3] foldr f z l = case l of [] -> z ; (x:xs) -> f x (foldr f z xs) logische Programmierung: append(a,b,[1,2,3]). append([],ys,ys). append([x XS],YS,[X ZS]):-append(XS,YS,ZS). Constraint-Programmierung (set-logic QF_LIA) (set-option :produce-models true) (declare-fun a () Int) (declare-fun b () Int) (assert (and (>= a 5) (<= b 30) (= (+ a b) 20))) (check-sat) (get-value (a b))
6 Deklarative vs. imperative Programmierung deklarativ (beschreibend) Programm: Repräsentation einer Aufgabe Programmelemente: Ausdrücke (Terme), Formeln, Gleichungen Programmierung: Modellierung der Aufgabe Ausführung: Lösung des beschriebenen Problems durch Standardverfahren z.b. logisches Schließen, Umformung von Ausdrücken imperativ zustandsorientiert (von-neumann-typ) Programm: Repräsentation eines Algorithmus Programmelemente: Ausdrücke und Anweisungen Programmierung: Modellierung eines Verfahrens zur Lösung einer Aufgabe Ausführung des Lösungsverfahrens durch schrittweise Zustandsänderungen (Speicherbelegung)
7 Definition deklarativ: jedes (Teil-)Programm/Ausdruck hat einen Wert... und keine weitere (versteckte) Wirkung. Werte können sein: klassische Daten (Zahlen, Listen, Bäume... ) Funktionen (Sinus,... ) Aktionen (Datei schreiben,... )
8 Softwaretechnische Vorteile der deklarativen Programmierung: Beweisbarkeit : Rechnen mit Programmen wie in der Mathematik mit Termen Sicherheit : es gibt keine Nebenwirkungen und Wirkungen sieht man bereits am Typ Wiederverwendbarkeit : durch Entwurfsmuster (= Funktionen höherer Ordnung) Effizienz : durch Programmtransformationen im Compiler Parallelisierbarkeit : durch Nebenwirkungsfreiheit
9 Beispiel Spezifikation/Test import Test.SmallCheck append :: [t] -> [t] -> [t] append x y = case x of [] -> y h : t -> h : append t y associative f = \ x y z -> f x (f y z) == f (f x y) z test1 = smallcheck (associative (append::[int]->[int]->[int])) Übung: Kommutativität (formulieren und testen)
10 Beispiel Verifikation app :: [t] -> [t] -> [t] app x y = case x of [] -> y h : t -> h : app t y zu beweisen: app x (app y z) == app (app x y) z Beweismethode: Induktion nach x. Induktionsanfang: x == []... Induktionsschritt: x == h : t...
11 Deklarative Programmierung in der Lehre funktionale Programmierung: diese Vorlesung logische Programmierung: in LV Künstliche Intelligenz Constraint -Programmierung: als Master-Wahlfach Beziehungen zu weiteren LV: Voraussetzungen Bäume, Terme (Alg.+DS, TGI) Logik (TGI, Digitaltechnik, Softwaretechnik) Anwendungen: Softwarepraktikum weitere Sprachkonzepte in LV Prinzipien v. Programmiersprachen LV Programmverifikation (vorw. f. imperative Programme)
12 Gliederung der Vorlesung Terme, Termersetzungssysteme algebraische Datentypen, Pattern Matching, Rekursive Datenypen, Rekursionsschemata Funktionen (polymorph, höherer Ordnung), Lambda-Kalkül Typklassen zur Steuerung der Polymorphie Bedarfsauswertung, unendl. Datenstrukturen
13 Organisation der Lehrveranstaltung jede Woche eine Vorlesung Hausaufgaben: schriftliche Übungen, autotool jede Woche eine Übung / Praktikum Beispiele, Besprechung der schriftlichen Aufgaben, autotool Prüfungsvorleistung: regelmäßiges (d.h. innerhalb der jeweiligen Deadline) und erfolgreiches (ingesamt 50% der Pflichtaufgaben) Bearbeiten von Übungsaufgaben. Prüfung: Klausur (ohne Hilfsmittel)
14 Literatur Skript voriges Semester: fop/folien/main Folien aktuelles Semester: http: // Bücher: Graham Hutton: Programming in Haskell, Cambridge 2007 Klassiker (englisch): deutsch: Peter Pepper und Petra Hofstedt: Funktionale Programmierung. Sprachdesign und Programmiertechnik Springer 2006 Manuel Chakravarty und Gabriele Keller: Einführung in die Programmierung mit Haskell Pearson 2004 online: Informationen, Download, Dokumentation, Tutorials,...
15 Werkzeug und Stil Die Grenzen meiner Sprache bedeuten die Grenzen meiner Welt. Ludwig Wittgenstein speziell in der Informatik: We are all shaped by the tools we use, in particular: the formalisms we use shape our thinking habits, for better or for worse, and that means that we have to be very careful in the choice of what we learn and teach, for unlearning is not really possible. (Many years ago, if I could use a new assistant, one prerequisite would be No prior exposure to FORTRAN", and at high schools in Siberia, the teaching of BASIC was not allowed.) Edsger W. Dijkstra aus E. W. Dijkstra Archive
16 Konzepte und Sprachen Funktionale Programmierung ist ein Konzept. Realisierungen: in prozeduralen Sprachen: Unterprogramme als Argumente (in Pascal) Funktionszeiger (in C) in OO-Sprachen: Befehlsobjekte Multi-Paradigmen-Sprachen: Lambda-Ausdrücke in C#, Scala, Clojure funktionale Programmiersprachen (LISP, ML, Haskell) Die Erkenntnisse sind sprachunabhängig. A good programmer can write LISP in any language. Learn Haskell and become a better Java programmer.
17 Geschichte ab ca Alonzo Church λ-kalkül ab ca John McCarthy LISP ab ca Peter Landin ISWIM ab ca John Backus FP Robin Milner ML David Turner Miranda ab 1987 Haskell
18 Warum Haskell? deklarativ, Nähe zum (mathematischen) Modell keine Nebenwirkungen (klare Semantik) Funktionen sind Daten (Funktionen höherer Ordnung) starkes Typsystem Typklassen lazy evaluation (ermöglicht Rechnen mit unendlichen Datenstrukturen) kompakte Darstellung (kurze Programme) Modulsystem
19 Entwicklung von Haskell-Programmen Haskell-Interpreter: ghci, Hugs Haskell-Compiler: ghc Entwicklungsumgebungen: alles kostenlos und open source Real Programmers (
20 Wiederholung: Terme Signatur (funktional) Σ (Σ F ) ist Menge von Funktionssymbolen mit Stelligkeiten Term t = f (t 1,..., t k ) in Signatur Σ ist Funktionssymbol der Stelligkeit k: (f, k) Σ der Stelligkeit k mit Argumenten t 1,..., t k, die selbst Terme sind. Term(Σ, X) = Menge aller Terme über Signatur Σ mit Individuenvariablen aus X Graphentheorie: ein Term ist ein gerichteter, geordneter, markierter Baum Datenstrukturen: Funktionssymbol = Konstruktor, Term = Baum
21 Beispiele: Signatur, Terme Signatur: Σ 1 = {Z /0, S/1, f /2} Elemente aus Term(Σ 1 ): Z (), S(S(Z ())), f (S(S(Z ())), Z ()) Signatur: Σ 2 = {E/0, A/1, B/1} Elemente aus Term(Σ 2 ):...
22 Haskell-Programme Programm: Menge von Funktions-Definitionen Gleichungen zwischen Termen Ausdruck: Term Ausführung: Auswertung des Ausdruckes (Bestimmung seines Wertes) Pattern matching, Reduktion, (Termersetzung) Semantik: Funktion von Eingabe (Ausdruck) auf Ausgabe (Wert) keine Variablen, also keine Programmzustände (kein Aufruf-Kontext) Wert jeder Funktion(sanwendung) hängt ausschließlich von den Werten der Argumente ab
23 Syntax Ausdrücke : Terme z.b. 2 + x * 7 oder double 2 Funktionsdefinition : Gleichung zwischen zwei Ausdrücken z.b. inc x = x + 1 Programm : Folge (Liste) von Funktionsdefinitionen Ausdruck
24 Ausdrücke Ausdruck = Term (Baumstruktur) Jeder Ausdruck hat einen Typ und einen Wert Berechnung des Wertes durch schrittweise Reduktion (Termersetzung)
25 Beispiele Ausdruck 7 hat den Typ Int den Wert 7 Ausdruck 3 * hat den Typ Int den Wert... Reduktion : (rekursive) Berechnung des Wertes
26 Funktionsdeklarationen double :: Int -> Int double x = x + x (Typdeklaration) (Funktionsdefinition) Ausdruck double 3 den Typ Int den Wert 6 hat Ausdruck double (double 3) hat den Typ Int den Wert... Ausdruck double hat den Typ Int -> Int den Wert x x + x (mathematische Notation) λx.(x + x) (λ-kalkül)
27 Was bisher geschah deklarative Programmierung funktional: Programm: Menge von Termgleichungen, Term Auswertung: Pattern matching, Termumformungen logisch: Programm: Menge von Regeln (Horn-Formeln), Formel Auswertung: Unifikation, Resolution funktionale Programmierung in Haskell: nebenwirkungsfrei lazy evaluation (ermöglicht unendliche Datentypen) kompakte Darstellung Praktikum: Termersetzung, ghci, Prelude
28 Bezeichnungen für Teilterme Position : Folge von natürlichen Zahlen (bezeichnet einen Pfad von der Wurzel zu einem Knoten) Beispiel: für Signatur Σ = {(g, 2), (f, 1), (c, 0)} und Term t = f (g(f (f (c)), c)) TermΣ, ist [0, 1] eine Position in t, aber [1], [0, 1, 0], [0, 0, 1] nicht Pos(t) Menge aller Positionen des Terms t Term(Σ, X) (rekursive) Definition: für t = f (t 1,..., t k ) gilt Pos(t) = {[]} {[i 1] ++{p i {1,..., k} p Pos(t i )}. dabei bezeichnen: [] die leere Folge, [i] die Folge der Länge 1 mit Element i, ++ den Verkettungsoperator für Folgen
29 Operationen mit (Teil)Termen t[p] t[p := s] : Teilterm von t an Position p Beispiele: f (g(f (f (c)), c))[0, 0] = f (f (c)) f (g(f (f (c)), c))[0, 1] =... (induktive) Definition (über die Länge von p): IA p = [] : t[] = t IS p = i ++p : f (t 1,..., t n )[p] = t i [p ] : wie t, aber mit Term s statt t[p] an Position p Beispiele: f (g(f (f (c)), c))[[0, 0] := c] = f (g(c, c)) f (g(f (f (c)), c))[[0, 1] := f (c)] =... (induktive) Definition (über die Länge von p):...
30 Operationen mit Variablen in Termen Menge Term(Σ, X) aller Terme über Signatur Σ mit Variablen aus X Beispiel: Σ = {Z /0, S/1, f /2}, X = {y}, f (Z (), y) Term(Σ, X). Substitution σ: partielle Abbildung X Term(Σ, X) Beispiel: σ 1 = {(y, S(Z ()))} eine Substitution auf einen Term anwenden: tσ: Intuition: wie t, aber statt v X immer σ(v) Beispiel: f (Z (), y)σ 1 = f (Z (), S(Z ())) Definition durch Induktion über t
31 Termersetzungssysteme Daten : Terme (ohne Variablen) Regel : Paar (l, r) von Termen mit Variablen Programm R: Menge von Regeln Bsp: R = {(f (Z (), y), y), (f (S(x), y), S(f (x, y)))} Relation R : Menge aller Paare (t, t ) mit es existiert (l, r) R es existiert Position p in t es existiert Substitution σ : (var(l) var(r)) Term(Σ) so dass t[p] = lσ und t = t[p := rσ].
32 Termersetzungssysteme als Programme R beschreibt einen Schritt der Rechnung von R, transitive Hülle R beschreibt Folge von Schritten. Resultat einer Rechnung ist Term in R-Normalform (ohne R -Nachfolger) Dieses Berechnungsmodell ist im allgemeinen nichtdeterministisch R 1 = {C(x, y) x, C(x, y) y} (ein Term kann mehrere R -Nachfolger haben, ein Term kann mehrere Normalformen erreichen) nicht terminierend R 2 = {p(x, y) p(y, x)} (es gibt eine unendliche Folge von R -Schritten, es kann Terme ohne Normalform geben)
33 Konstruktor-Systeme Für TRS R über Signatur Σ: Symbol s Σ heißt definiert, wenn (l, r) R : l[] = s(...) Konstruktor, sonst Das TRS R heißt Konstruktor-TRS, falls die definierten Symbole links nur in den Wurzeln vorkommen (rechts egal) Übung: diese Eigenschaft formal spezifizieren Beispiele: R 1 = {a(b(x)) b(a(x))} über Σ 1 = {a/1, b/1}, R 2 = {f (f (x, y), z) f (x, f (y, z))} über Σ 2 = {f /2}: definierte Symbole? Konstruktoren? Konstruktor-System? Funktionale Programme sind ähnlich zu Konstruktor-TRS.
34 Selbsttest-Übungsaufgaben zur Klausur-Vorbereitung (statt Praktikum diese Woche) zu Signaturen Termen Substitutionen Termersetzungsysstemen Normalformen unter ss14/fop/folien/main/node28.html
35 Funktionale Programme... sind spezielle Term-Ersetzungssysteme. Beispiel: Signatur: S einstellig, Z nullstellig, f zweistellig. Ersetzungssystem {f (Z, y) y, f (S(x), y) S(f (x, y))}. Startterm f (S(S(Z )), S(Z )). entsprechendes funktionales Programm: data N = Z S N f :: N -> N -> N f x y = case x of { Z -> y ; S x -> S (f x y) } Aufruf: f (S (S Z)) (S Z) Auswertung = Folge von Ersetzungsschritten R Resultat = Normalform (hat keine R -Nachfolger)
36 data und case typisches Vorgehen beim Programmieren einer Funktion f :: T ->... Für jeden Konstruktor des Datentyps data T = C1... C2... schreibe einen Zweig in der Fallunterscheidung f x = case x of C1... ->... C2... ->...
37 Peano-Zahlen data N = Z S N deriving Show plus :: N -> N -> N plus x y = case x of Z -> y S x -> S (plus x y) Beispiel (Tafel): Multiplikation
38 Was bisher geschah Wiederholung Signatur, Term Termersetzungssysteme (TRS) Konstruktoren, definierte Symbole Konstruktor-Systeme funktionale Programmierung Programm: Menge von Termgleichungen (TRS) Ausdruck (dessen Wert zu bestimmen ist): Term Auswertung: Pattern matching, Termumformungen Haskell: nebenwirkungsfrei kompakte Darstellung Praktikum: ghci, Prelude, Typen, Hoogle
39 Vordefinierte Haskell-Datentypen einfache Datentypen, z.b. Int ganze Zahlen (feste Länge) Integer ganze Zahlen (beliebige Länge) Bool Wahrheitswerte (False, True) Char ASCII-Symbole Float, Double zusammengesetzt (Typkonstruktoren): Tupel (a, b), (a, b, c), (a1, a2,...) z.b. (1, True, B ) :: (Int, Bool, Char) Listen (polymorph) [a], z.b. [3,5,2] :: [Int], [[ I, N ],[ B ]] :: [[Char]] String = [Char], z.b. "INB" = [ I, N, B ]
40 Definition von Funktionen Programmstrukturen: Verzweigung (Fallunterscheidung) Rekursion Beispiel: sumto :: Int -> Int sumto n = if n < 0 then 0 else n + sumto (n-1)
41 Funktionsdeklarationen (Wiederholung) add :: Int -> Int -> Int (Typdeklaration) add x y = x + y (Funktionsdefinition) Ausdruck add 3 5 hat den Typ Int den Wert 8 Ausdruck add (add 3 5) 1 hat den Typ Int den Wert... Ausdruck add hat den Typ Int -> Int -> Int den Wert (x, y) x + y (mathematische Notation) λx.λy.(x + y) (λ-kalkül) Ausdruck add 3 hat den Typ Int -> Int den Wert y 3 + y (mathematische Notation) λy.(3 + y) (λ-kalkül) (partielle Anwendung von add)
42 Typinferenz Typinferenzregel: f :: A B e :: A f e :: B Man bemerke die Analogie zur logischen Inferenzregel Modus Ponens: A B B A Beispiel: Typ von add 3, add 3 5
43 Beispiele Typinferenz True :: Bool False :: Bool neg :: Bool -> Bool neg True = False neg False = True Typ von neg True, neg (neg True) len :: [a] -> Int gerade :: Int -> Bool Typ von [1,2,3], len [1,2,3], gerade ( len [1,2,3] )
44 Currying Idee: Jede Funktion mit mehreren Argumenten lässt sich als geschachtelte Funktionen mit je einem Argument auffassen (und aufschreiben) Beispiel: Die folgenden Zeilen definieren dieselbe Funktion vom Typ g :: Int -> Int -> Bool g m n = m < n g m = \ n -> m < n (g m) = λn.(m < n) g = \ m n -> m < n g = λm.λn.(m < n) mit Argument-Tupel (Achtung anderer Typ): g :: (Int, Int) -> Bool g (m, n) = m < n in mathematischer Notation: zweistellig: C (A B) ist isomorph zu (C B ) A (n 1)-stellig: A (A 1 A n 1 ) n ist isomorph zu ( ( A A n 1 n ) ) A1
45 Konstruktion zusammengesetzter Datentypen Operationen: (kartesisches) Produkt Vereinigung (Fallunterscheidung) z.b. Aufzählungstypen Rekursion, z.b. Listen, Bäume, Peano-Zahlen Potenz, Funktionen
46 Algebraische Datentypen data Foo = Foo { bar :: Int, baz :: String } deriving Show Bezeichnungen (benannte Notation): data Foo ist Typname Foo {.. } ist Konstruktor bar, baz sind Komponenten x :: Foo x = Foo { bar = 3, baz = "hal" } Bezeichnungen (positionelle Notation) data Foo = Foo Int String y = Foo 3 "bar" Mathematisch: Produkt Foo = Int String
47 Datentyp mit mehreren Konstruktoren Beispiel (selbst definiert): data T = A { foo :: Int } B { bar :: String } deriving Show Beispiel (in Prelude vordefiniert) data Bool = False True data Ordering = LT EQ GT Mathematisch: (disjunkte) Vereinigung Bool = { False } { True }
48 Fallunterscheidung, Pattern Matching data T = A { foo :: Int } B { bar :: String } Fallunterscheidung: f :: T -> Int f x = case x of A {} -> foo x B {} -> length $ bar x Pattern Matching (Bezeichner n,l werden lokal gebunden): f :: T -> Int f x = case x of A { foo = n } -> n B { bar = l } -> length l
49 Rekursive Datentypen Wiederholung Peano-Zahlen: data Nat = Z S Nat Menge aller Peano-Zahlen: Nat = {Z} {Sn n Nat} Addition: add :: Nat -> Nat -> Nat add Z y = y add ( S x ) y = S ( add x y ) oder add :: Nat -> Nat -> Nat add x y = case x of Z -> y S x -> S ( add x y ) Definition weiterer Operationen: Multiplikation, Potenz
50 Wiederholung ADT Nat Sorten: N (natürliche Zahlen) Signatur: Z :: N S :: N -> N add :: N -> N -> N mult :: N -> N -> N... Axiome: x y u: add Z x = x = add x Z add x y = add y x add x ( add y u ) = add ( add x y ) u mult Z x = Z = mult x Z mult ( S Z ) x = x = mult x ( S Z ) mult x y = mult y x mult x ( mult y u ) = mult ( mult x y ) u... Nachweis durch strukturelle Induktion (Tafel)
51 Wiederholung Strukturelle Induktion Induktive Definition strukturierter Daten (rekursive Datentypen): IA: Basisfälle IS: rekursive Fälle, Vorschrift zur Konstruktion zusammengesetzter Daten Induktive Definition von Funktionen über strukturierten Daten: IA: Definition des Funktionswertes für Basisfälle IS: Berechnung des Funktionswertes der zusammengesetzten Daten aus den Funktionswerten der Teile Prinzip der strukturellen Induktion zum Nachweis einer Aussage A über strukturierte Daten: IA: Nachweis, dass A für alle Basisfälle gilt IS: Hypothese (Voraussetzung): A gilt für Teildaten Behauptung: A gilt für aus Teildaten zusammengesetzte Daten Induktionsbeweis: Nachweis, dass Behauptung aus Hypothese folgt.
52 Was bisher geschah Deklarative vs. imperative Programmierung Funktionale Programmierung: Programm: Menge von Gleichungen von Termen (Konstruktor-System) Ausdruck hat Typ und Wert (zu berechnen) Ausführung: Pattern matching, Termersetzung Haskell: Algebraische Datentypen und Pattern Matching Rekursive Datentypen (Peano-Zahlen) Rekursive Funktionen strukturelle Induktion
53 Wiederholung Haskell-Typen vordefinierte Typen, z. B. Bool, Char, Int, Float, String,... Typvariablen, z.b. a, b,... Konstruktion zusammengestzter Typen: selbstdefiniert constr typ1... typn Listen-Konstruktor [ typ ] Tupel-Konstruktor ( typ1,..., typn ) Funktions-Konstruktor typ1 -> typ2
54 Algebraische Datentypen Wiederholung Operationen: Produkt A B Beispiel: data Punkt = Punkt { x :: Float, y :: Float} data Kreis = Kreis { mp :: Punkt, radius :: Float } (disjunkte) Vereinigung A B Beispiel Wahrheitswerte (vordefiniert) data Bool = True False data Shape = Circle { mp :: Punkt, radius :: Float } Rect { ol, ur :: Punkt} umfang :: Shape -> Float umfang s = case s of Circle {} -> 2 * pi * ( radius s ) Rect ol ur ->... Potenz A B = {f : B A} z.b. gerade_laenge :: String -> Bool
55 Algebraische Datentypen Beispiel data HR = N O S W data Turn = Links Rechts Um dreh :: Turn -> HR -> HR dreh Rechts x = case x of N -> O O -> S S -> W W -> N dreh Links x =... drehs :: [ Move ] -> HR -> HR drehs ( m : ms ) x = dreh m ( drehs ms x )
56 Algebraische Datentypen Beispiele data Pair a b = Pair a b data Either a b = Left a Right b data Maybe a = Nothing Just a (Produkt) (Vereinigung) (Vereinigung) Binärbäume (rekursiv): data Bin a = Leaf Branch (Bin a) a (Bin a) Spezialfall Listen (Unärbäume): data List a = Nil Cons a (List a) Bäume (mit beliebigen Knotengraden): data Tree a = Node a (List (Tree a))
57 Typsynonyme (Um-)Benennung vorhandener Typen (meist als Kurzform) Beispiel: type String = [ Char ] type Name = String type Telefonnummer = Int type Telefonbuch = [ ( Name, Telefonnummer ) ] nummern :: Name -> Telefonbuch -> [ Telefonnummer ] nummern name [] = [] nummern name ( ( n, t ) : rest )... allgemeiner: Wörterbücher type Woerterbuch a b = [ ( a, b ) ] rekursive Typen sind nicht als Typsynonym definierbar
58 Typsynonyme Beispiel Zwei-Personen-Brettspiel (auf rechteckigem Spielfeld) Spieler ziehen abwechselnd Jeder Spieler hat Spielsteine seiner Farbe auf mehreren Positionen des Spielfeldes Spielfeld: type Feld = ( Int, Int ) type Belegt = [ Feld ] type Spieler = Bool Spielzustand: type Zustand = ( Belegt, Belegt, Spieler ) Spiel: type Spiel = [ Zustand ]
59 Polymorphie nicht polymorphe Typen: tatsächlicher Argumenttyp muss mit dem deklarierten Argumenttyp übereinstimmen: f :: A B e :: A (f e) :: B polymorphe Typen: Typ von f :: A -> B und Typ von e :: A können Typvariablen enthalten. A und A müssen unfizierbar (eine gemeinsame Instanz besitzen) aber nicht notwendig gleich sein. σ = mgu(a, A ) allgemeinster Unifikator Typ von f wird dadurch spezialisiert auf σ(a) σ(b) Typ von e wird dadurch spezialisiert auf σ(a ) allgemeinster Typ von ( f e ) ist dann σ(b)
60 Wiederholung Substitutionen Substitution: partielle Funktion θ : X Term(Σ, X) Notation als Aufzählung [x t 1, y t 2,...] Anwendung einer Substitution: s[x t] ist der Term, welcher aus dem Term s durch Ersetzung jedes Vorkommens der Variable x durch t entsteht ϕ[x t] ist die Formel, die aus der Formel ϕ durch Ersetzung jedes freien Vorkommens der Variable x durch t entsteht Beispiele: g(x, f (a))[x b] = g(b, f (a)) h(y, x, f (g(y, a)))[x g(a, z), y a] = h(a, g(a, z), f (g(a, a))) g(x, f (a))[x b, y a] = g(b, f (a)) g(b, f (y))[x b, y a] = g(b, f (a)) für θ = [x b], σ = [y f (a)] (auch θ(x) = b, σ(y) = f (a) ) gilt (h((b, f (y)), k(x)))θσ = σ(θ(h((b, f (y)), k(x))) = σ(h((b, f (y)), k(b)) = h((b, f (f (a))), k(b))
61 Unifikator Substitution θ heißt genau dann Unifikator der Terme t 1 und t 2 (θ unifiziert t 1 und t 2 ), wenn θ(t 1 ) = θ(t 2 ) gilt. Beispiele: 1. θ = [x b, y a] unifiziert t 1 = g(x, f (a)) und t 2 = g(b, f (y)) 2. [x g(g(y)), z g(y)] unifiziert f (x, g(y)) und f (g(z), z) (und f (g(z), g(y)). 3. [x g(g(a)), y a, z g(a)] unifiziert f (x, g(y)) und f (g(z), z). 4. [x g(g(y)), z g(y), v f (a)] unifiziert f (x, g(y)) und f (g(z), z). Terme t 1, t 2 heißen genau dann unifizierbar, wenn ein Unifikator für t 1 und t 2 existiert. Beispiele: 1. g(x, f (a)) und g(b, f (y)) sind unifizierbar, f (g(a, x)) und f (g(f (x), a)) nicht. 2. h(a, f (x), g(a, y)) und h(x, f (y), z) sind unifizierbar, h(f (a), x) und h(x, a) nicht.
62 Was bisher geschah Deklarative vs. imperative Programmierung Funktionale Programmierung: Programm: Menge von Gleichungen von Termen (Konstruktor-System) Ausdruck hat Typ und Wert (zu berechnen) Ausführung: Pattern matching, Termersetzung Haskell: Algebraische Datentypen und Pattern Matching Rekursive Datentypen (Peano-Zahlen) Rekursive Funktionen strukturelle Induktion
63 Typ-Inferenz in Haskell Inferenzregel: f :: A B e :: A (f e) :: B für polymorphe Typen: f :: A B e :: A (f e) ::? Unifikator σ der Typausdrücke (Terme) A und A (Substitution mit σ(a) = σ(a )) f :: σ(a) σ(b) e :: σ(a ) (f e) :: σ(b)
64 Wiederholung Unifikator Substitution θ heißt genau dann Unifikator der Terme t 1 und t 2 (θ unifiziert t 1 und t 2 ), wenn θ(t 1 ) = θ(t 2 ) gilt. Beispiele: 1. θ = [x b, y a] unifiziert t 1 = g(x, f (a)) und t 2 = g(b, f (y)) 2. [x g(g(y)), z g(y)] unifiziert f (x, g(y)) und f (g(z), z) (und f (g(z), g(y)). 3. [x g(g(a)), y a, z g(a)] unifiziert f (x, g(y)) und f (g(z), z). 4. [x g(g(y)), z g(y), v f (a)] unifiziert f (x, g(y)) und f (g(z), z). Terme t 1, t 2 heißen genau dann unifizierbar, wenn ein Unifikator für t 1 und t 2 existiert. Beispiele: 1. g(x, f (a)) und g(b, f (y)) sind unifizierbar, f (g(a, x)) und f (g(f (x), a)) nicht. 2. h(a, f (x), g(a, y)) und h(x, f (y), z) sind unifizierbar, h(f (a), x) und h(x, a) nicht.
65 (Keine) Ordnung auf Unifikatoren Für zwei Unifikatoren σ, θ der Terme s, t gilt: Relation R auf Substitutionen: (σ, θ) R gdw. ρ : σ ρ = θ (Man bemerke die Analogie zur Teilerrelation) Beispiele: ([x y], [x a, y a]) R ([x y], [y x]) R ([y x], [x y]) R Diese Relation R ist reflexiv und transitiv, aber nicht antisymmetrisch.
66 Ordung auf Unifikatoren σ heißt genau dann allgemeiner als θ, wenn eine Substitution ρ (die nicht nur Umbenennung ist) existiert, so dass σ ρ = θ Diese Relation ist eine Halbordnung Beispiele: Unifikatoren für f (x, g(y)), f (g(z), z) 1. Unifikator [x g(g(y)), z g(y)] ist allgemeiner als [x g(g(a)), z g(a)] ρ = [y a] 2. Unifikator [x g(g(y)), z g(y)] ist allgemeiner als [x g(g(y)), z g(y), v g(b)] ρ = [v g(b)]
67 Allgemeinster Unifikator Zu unifizierbaren Termen s, t existiert (bis auf Umbenennung der Variablen) genau ein Unifikator θ mit der folgenden Eigenschaft: Für jeden Unifikator σ für s, t ist θ allgemeiner als σ. Dieser heißt allgemeinster Unifikator θ = mgu(s, t) von s und t. (analog ggt) Beispiele: mgu(f (x, a), f (g(b), y)) = [x g(b), y a] mgu(f (x, g(y)), f (g(z), z)) = [x g(g(y)), z g(y)]
68 Unifizierbarkeit Jeder Term t ist mit t unifizierbar. allgemeinster Unifikator mgu(t, t) = [] Jeder Term t ist mit jeder Variable x X, die nicht in t vorkommt, unifizierbar. allgemeinster Unifikator mgu(t, t) = [x t] f (t 1,..., t n ) und g(s 1,..., s m ) sind nicht unifizierbar, falls f g oder n m θ ist Unifikator für f (t 1,..., t n ), f (s 1,..., s n ) gdw. i {1,..., n} : θ unifiziert t i und s i
69 Unifikation Aufgabe Eingabe: Terme s, t Term(Σ, X) Ausgabe: ein allgemeinster Unifikator (mgu) σ : X Term(Σ, X) mit sσ = tσ. Satz: Jedes Unifikationsproblem ist entweder gar nicht oder bis auf Umbenennung eindeutig lösbar.
70 Unifikation Algorithmus Berechnung von σ = mgu(s, t) für Terme s, t Term(Σ, X) durch Fallunterscheidung: s X: falls s var(t), dann σ = [s t], sonst nicht unifizierbar t X: symmetrisch s = f (s 1,..., s m ) und t = g(t 1,..., t n ): falls f g oder m n, dann nicht unifizierbar sonst σ = mgu(s 1, t 1 ) mgu(s m, t m ) Dabei gilt für jede Substitution θ: θ nicht unifizierbar = nicht unifizierbar θ = nicht unifizierbar
71 Unifikationsalgorithmus Beispiele mgu(f (x, h(y), y), f (g(z), z, a)) = [x g(h(a)), z h(a), y a] mgu (k(f (x), g(y, h(a, z))), k(f (g(a, b)), g(g(u, v), w))) = [x g(a, b), y g(u, v), w h(a, z)] mgu(k(f (a), g(x)), k(y, y)) existiert nicht mgu(f (x, g(a, z)), f (f (y), f (x)) existiert nicht mgu(f (x, x), f (y, g(y)) existiert nicht mgu(f (x, g(y)), f (y, x) existiert nicht
72 Unifikation von Haskell-Typen Beispiele last :: [a] -> a Typ von [ 3, ] ist [Int] angewendete Instanz der Funktion last :: [Int] -> Int, der Typ von last [ 3, ] ist also Int take :: Int -> [a] -> [a] Typ von take 1? Typ von take 1 [ "foo", "bar" ]?
73 Was bisher geschah Deklarative vs. imperative Programmierung Funktionale Programmierung: Programm: Menge von Gleichungen von Termen (Konstruktor-System) Ausdruck hat Typ und Wert (zu berechnen) Ausführung: Pattern matching, Termersetzung Funktionale Programmierung in Haskell rekursive Funktionen algebraische Datentypen und Pattern Matching rekursive Datentypen (Peano-Zahlen) strukturelle Induktion Typen, Typ-Konstruktoren, Typ-Synonyme Polymorphie Typ-Inferenz, Unifikation
74 Datentyp Liste (polymorph) data List a = Nil Cons { head :: a, tail :: List a} oder kürzer (vordefiniert) data [a] = [] a : [a] Pattern Matching: f :: [a] ->... f xs = case xs of [] ->... (x : xss) ->... Beispiel: append :: [a] -> [a] -> [a] append xs ys = case xs of [] -> ys (x : xss) -> x : (append xss ys)
75 Strukturelle Induktion über Listen zum Nachweis von Eigenschaften wie z.b. append xs [] = xs append ist assoziativ, d.h append xs (append ys zs) = append (append xs ys) zs Länge der Eingabeliste len :: [a] -> Int len xs = case xs of [] -> 0 (x : xss) -> 1 + len xss Strukturelle Induktion zum Nachweis von len ( append xs ys ) = len xs + len ys
76 Mehr Beispiele Summe aller Elemente der Eingabeliste sum :: [Int] -> Int sum xs = case xs of [] ->... (x : xss) ->... jedes Element der Eingabeliste verdoppeln doubles :: [Int] -> [Int] doubles xs = case xs of [] -> [] ( y : ys ) ->... : (doubles ys) Strukturelle Induktion zum Nachweis von sum ( doubles xs ) = 2 * ( sum xs )
77 Sortierte Listen (aufsteigend geordnet) sortiert :: [Int] -> Bool sortiert xs = case xs of [] -> True [ _ ] -> True (x : y : ys) -> x <= y && sortiert (y : ys) sortiertes Einfügen: insert :: Int -> [Int] -> [Int] insert y xs = case xs of [] ->... ( x : xs ) -> if... then... else... Strukturelle Induktion zum Nachweis von: Aus sortiert xs folgt sortiert ( insert x xs )
78 List Comprehensions Motivation Menge der Quadrate aller geraden Zahlen zwischen 0 und 20: {i 2 i {0,..., 20} i 0 (mod 2)} Liste der Quadrate aller geraden Zahlen zwischen 0 und 20: ( i 2) i [0,...,20], i 0 (mod 2) Definition der Menge / Liste enthält: Generator i [0,..., 20] Funktion 2 : N N Bedingung i 0 (mod 2) als List Comprehension in Haskell: [ i ^ 2 i <- [0.. 20], rem i 2 == 0]
79 List Comprehensions mit einem Generator [ f x x <-..] z.b. [ 3 * x x <- [1.. 5] ] mit mehreren Generatoren [ f x1.. xn x1 <-..,.., xn <-.. ] z.b. [ ( x, y ) x <- [1.. 3], y <- [0,1] ] [ (x, x * y, x + z) x <- [1.. 5], y <- [0.. 2], z <- [3..] ] mit Bedingungen: [ f x1.. xn x1 <-..,.., xn <-.., r1 xi xj,.., rk xi xj ] z.b. [ ( x, y ) x <- [1.. 5], y <- [ ], x + y > 5, rem x 2 == 0]
80 Beispiele [ ( x, y ) x <- [ ], y <- [ 4, 5 ] ] [ ( x, y ) y <- [ ], x <- [ 4, 5 ] ] [ x * y x <- [ ], y <- [ ] ] [ x * y x <- [1.. 3], y <- [2.. 4], x < y ] [ a _ <- [1.. 4] ] [ [1.. n] n <- [0.. 5] ] hat welchen Typ? [ x xs <- xss, x <- xs ] ] xss hat welchen (allgemeinsten) Typ?
81 Mehr Beispiele teiler :: Int -> [ Int ] teiler x = [ y y <- [ 1.. x ], rem x y == 0 ] prim :: Int -> Bool prim x = ( teiler x ) == [ 1, x ] primzahlen :: [ Int ] primzahlen = [ x x <- [ 2.. ], prim x ] ( später auch anders )
82 Was bisher geschah Deklarative vs. imperative Programmierung Funktionale Programmierung: Programm: Menge von Gleichungen von Termen (Konstruktor-System) Ausdruck hat Typ und Wert (zu berechnen) Ausführung: Pattern matching, Termersetzung Funktionale Programmierung in Haskell rekursive Funktionen algebraische Datentypen und Pattern Matching rekursive Datentypen Peano-Zahlen, Listen strukturelle Induktion Typen, Polymorphie, Typ-Inferenz
83 Datentyp Binärbaum (polymorph) data Bintree a = Leaf {} Branch { left :: Bintree a, key :: a, right :: Bintree a } Beispiel: t :: Bintree Int t = Branch { left = Branch { left = Leaf {}, key = 5, right = Leaf {} }, key = 3, right = Branch { left = Leaf {}, key = 2, right = Branch { left = Leaf {}, key = 4, right = Leaf {} }}}
84 Pattern Matching data Bintree a = Leaf {} Branch { left :: Bintree a, key :: a, right :: Bintree a } f :: Bintree a ->.. f t = case t of Leaf {} ->.. Branch {} ->.. oder tiefer: f :: Bintree a ->.. f t = case t of Leaf {} ->.. Branch { left = l, key = k, right = r } ->..
85 Rekursion über binäre Bäume Beispiele Anzahl der inneren Knoten count :: Bintree a -> Int count t = case t of Leaf {} -> 0 Branch {} -> count (left t) count (right t) Anzahl der Blätter: leaves :: Bintree a -> Int leaves t = case t of Leaf {} ->... Branch {} ->... Summe der Schlüssel (Int): bt_sum :: Bintree Int -> Int bt_sum t = case t of Leaf {} ->... Branch {} ->...
86 Mehr Beispiele jeden Schlüssel verdoppeln doubles :: Bintree Int -> Bintree Int doubles t = case t of Leaf {} -> Leaf {} Branch {} ->... inorder :: Bintree a -> [a] inorder t = case t of Leaf {} -> [] Branch {} ->... vollständiger binärer Baum der Höhe h: full :: Int -> Bintree Int full h = if h > 0 then Branch { left = full (h-1), key = h, right = full (h-1) } else Leaf {}
87 Strukturelle Induktion über Binärbäume z.z. Jeder Binärbaum t mit Schlüsseln vom Typ a hat die Eigenschaft P IA (t = Leaf): z.z.: Leaf hat die Eigenschaft P IS IV: Binärbäume l und r erfüllen P IB: k :: a hat der Binärbaum Branch { left = l, key = k, right = r } die Eigenschaft P zum Nachweis von Eigenschaften wie z.b. ( t :: Bintree Int ) : bt_sum (doubles t) = 2 * bt_sum t ( t :: Bintree Int ) : bt_sum t = list_sum ( inorder t )
88 Was bisher geschah Deklarative vs. imperative Programmierung Funktionale Programmierung: Programm: Menge von Gleichungen von Termen (Konstruktor-System) Ausdruck hat Typ und Wert (zu berechnen) Ausführung: Pattern matching, Termersetzung Funktionale Programmierung in Haskell rekursive Funktionen algebraische Datentypen und Pattern Matching rekursive Datentypen Peano-Zahlen, Listen, Binärbäume strukturelle Induktion Typen, Polymorphie, Typ-Inferenz
89 Wiederholung Datentyp Binärbaum (polymorph) data Bintree a = Leaf {} Branch { left :: Bintree a, key :: a, right :: Bintree a } Beispiel: t :: Bintree Int t = Branch { left = Branch { left = Leaf {}, key = 1, right = Leaf {} }, key = 3, right = Branch { left = Leaf {}, key = 4, right = Branch { left = Leaf {}, key = 6, right = Leaf {} }}}
90 Binäre Suchbäume Suchbaum-Eigenschaft: Ein binärer Baum t :: Bintree Int ist genau dann ein Suchbaum, wenn seine Knoten in Inorder-Durchquerung (aufsteigend) geordnet sind. search_tree t = sortiert (inorder t) mit sortiert :: [ Int ] -> Bool sortiert [] = True sortiert [ x ] = True sortiert ( x : y : xs ) =... Einfügen eines Schlüssels in einen binären Suchbaum: insert :: Int -> Bintree Int -> Bintree Int insert x t = case t of Leaf {} -> Branch { left = Leaf {}, key = x, right = Leaf {} } Branch {} ->...
91 Sortieren durch Einfügen in binäre Suchbäume Einfügen mehrerer Schlüssel in binären Suchbaum: inserts :: [Int] -> Bintree Int -> Bintree Int inserts xs t = case xs of [] -> t ( x : xss ) ->... Sortieren durch Einfügen in binären Suchbaum: sort :: [Int] -> [Int] sort xs = inorder ( inserts xs Leaf )
92 Strukturelle Induktion über Bäume zum Nachweis von Eigenschaften wie z.b. bt_sum (insert x t) = x + bt_sum t Für jeden Suchbaum t ist inorder t sortiert. Einfügen, Löschen eines Knotens erhalten die Suchbaum-Eigenschaft.
93 Eingeschänkte Polymorphie reverse [1,2,3,4] = [4,3,2,1] reverse "foobar" = "raboof" reverse :: [a] -> [a] reverse ist polymorph Sortieren von Listen sort [5,1,4,3] = [1,3,4,5] sort "foobar" = "abfoor" sort :: [a] -> [a] --?? sort [sin,cos,log] =?? sort ist eingeschränkt polymorph Eingeschränkte Polymorphie in Haskell durch Typklassen
94 Beispiel Sortieren/Vergleichen Einfügen (in monotone Liste) insert :: Int -> [Int] -> [Int] insert x ys = case ys of [] -> [x] y : ys -> if x < y then.. else.. Sortieren durch Einfügen: sort :: [Int] -> [Int] sort xs = case xs of [] -> [] x : xs -> insert x (sort xs ) Einfügen/Sortieren für beliebige Typen: mit Vergleichsfunktion lt :: a -> a -> Bool als zusätzlichem Argument insert :: ( a -> a -> Bool ) -> a -> [a] -> [a] insert lt x ys =... if lt x y then...
95 Sortieren/Vergleichen Sortieren enthält Vergleiche < Für alle Typen a, die für die es eine Vergleichs-Funktion compare gibt, hat sort den Typ [a] -> [a]. sort :: Ord a => [a] -> [a] Ord ist eine Typklasse, definiert durch class Ord a where compare :: a -> a -> Ordering data Ordering = LT EQ GT
96 Instanzen Typen können Instanzen von Typklassen sein. (analog in OO: Klassen implementieren Interfaces) Für vordefinierte Typen sind auch die meisten sinnvollen Instanzen vordefiniert instance Ord Int ; instance Ord Char ;... weitere Instanzen kann man selbst deklarieren: data Student = Student { vorname :: String, nachname :: String, matrikel :: Int } instance Ord Student where compare s t = compare (matrikel s) (matrikel t)
97 Typen und Typklassen In Haskell sind unabhängig: 1. Deklaration einer Typklasse (= Deklaration von abstrakten Methoden) class C where { m ::... } 2. Deklaration eines Typs (= Sammlung von Konstruktoren und konkreten Methoden) data T = Instanz-Deklaration (= Implementierung der abstrakten Methoden) instance C T where { m =... } In Java sind 2 und 3 nur gemeinsam möglich class T implements C {... }
98 Typen mit Gleichheit class Eq a where (==) :: a -> a -> Bool (/=) :: a -> a -> Bool Beispiele: ( a == b ) = False (True /= False) = True ("ab" /= "ac") = True ([1,2] == [1,2,3]) = False (\ x -> 2 * x) == (\ x -> x + x) =?
99 Typen mit totaler Ordnung Instanzen der Typklasse Eq mit data Ordering = LT EQ GT class Eq a => Ord a where compare :: a -> a -> Ordering (<) :: a -> a -> Bool (<=) :: a -> a -> Bool (>) :: a -> a -> Bool (>=) :: a -> a -> Bool min :: a -> a -> a max :: a -> a -> a Beispiele: ( a < b ) = True (False < True) = True ("ab" < "ac") = True ([1,2] > [1,2,3]) = False (lexikographisch)
100 Klassen-Hierarchien Typklassen können in Beziehung stehen. Ord ist abgeleitet von Eq: class Eq a where (==) :: a -> a -> Bool class Eq a => Ord a where (<) :: a -> a -> Bool Ord ist Typklasse mit Typconstraint (Eq) also muss man erst die Eq-Instanz deklarieren, dann die Ord-Instanz.
101 Instanzen data Bool = False True instance Eq Bool where False == False = True True == True = True _ == _ = False zu definieren: instance Ord Bool where False < True = True _ < _ = False abgeleitet: x <= y = ( x < y ) ( x == y ) x > y = y < x x >= y = y <= x
102 Typen mit Operation zum (zeilenweisen) Anzeigen class Show a where show :: a -> String Beispiele: show 123 = "123" show True = "True" show [1,2] = "[1,2]" show (1, a,true) = "show (1, a,true)" Instanzen Bool, Char, Int, Integer, Float, Listen und Tupel von Instanzen
103 Typklasse Show Interpreter ghci gibt bei Eingabe exp (normalerweise) show exp aus. Man sollte (u. a. deswegen) für jeden selbst deklarierten Datentyp eine Show-Instanz schreiben.... oder schreiben lassen: deriving Show
104 Typen mit Operation zum Lesen class Read a where read :: String -> a Beispiele: ( read "3" :: Int ) = 3 ( read "3" :: Float ) = 3.0 ( read "False" :: Bool ) = False ( read " a " :: Char ) = a ( read "[1,2,3]" :: [Int] ) = [1,2,3] Instanzen Bool, Char, Int, Integer, Float, Listen und Tupel von Instanzen
105 Numerische Typen class (Eq a, Show a) => Num a where (+) :: a -> a -> a (-) :: a -> a -> a (*) :: a -> a -> a negate :: a -> a abs :: a -> a signum :: a -> a Beispiele: signum (-3) = -1 signum (-3.3) = -1.0 Instanzen Int, Integer, Float
106 Numerische Typen mit Division Ganzzahl-Division: class Num a => Integral a where div :: a -> a -> a mod :: a -> a -> a Instanzen Int, Integer Beispiel: 3 div 2 = 1 Division: class Num a => Fractional a where (/) :: a -> a -> a recip :: a -> a -> a Instanzen: Float, Double Beispiel: 3 / 2 = 0.6
107 Generische Instanzen class Eq a where (==) :: a -> a -> Bool Vergleichen von Listen (elementweise) wenn a in Eq, dann [ a ] in Eq: instance Eq a => Eq [a] where [] == [] = True (x : xs) == (y : ys) = (x == y) && ( xs == ys ) _ == _ = False instance Ord a => Ord [a] where compare [] [] = EQ compare [] (_:_) = LT compare (_:_) [] = GT compare (x:xs) (y:ys) = case compare x y of EQ -> compare xs ys other -> other
108 Abgeleitete Instanzen Deklaration eigener Typen als Instanzen von Standardklassen durch automatische Erzeugung der benötigten Methoden: Beispiele: data Bool = False True deriving (Eq, Ord, Show, Read) data Shape = Circle Float Rect Float Float deriving (Eq, Ord, Show, Read) z.b. (Circle 3 < Rect 1 2) == True data Maybe a = Nothing Just a deriving (Eq, Ord, Show, Read) z.b. (Just a == Just b ) == False
109 Was bisher geschah Deklarative vs. imperative Programmierung Deklarative Programmierung Funktionale Programmierung in Haskell: Algebraische Datentypen Pattern Matching (eingeschränkte) Polymorphie, Typklassen Rekursive Datentypen: Peano-Zahlen, Listen, binäre Bäume Rekursive Funktionen strukturelle Induktion
110 Funktionen als Daten bisher: f :: Int -> Int f x = 2 * x + 5 äquivalent: Lambda-Ausdruck f = \ x -> 2 * x + 5 Lambda-Kalkül: Alonzo Church 1936, Henk Barendregt 1984,... Funktionsanwendung: ( \ x -> B ) A = B [ x := A ] ist nur erlaubt, falls keine in A freie Variable durch ein λ in B gebunden wird.
111 Der Lambda-Kalkül... als weiteres Berechnungsmodell, (vgl. Termersetzungssysteme, Turingmaschine, Random-Access-Maschine) Syntax (induktive Definition): Die Menge der Lambda-Terme Λ(X) mit Variablen aus X ist IA: jede Variable ist ein Term: v X v Λ(X) IS: Applikation, Funktionsanwendung: Für alle F Λ(X), A Λ(X) gilt (FA) Λ(X) Abstraktion, Funktionsdefinition: Für alle v X, B Λ(X) gilt (λv.b) Λ(X) Semantik: eine Relation β auf Λ(X) (vgl. R für Termersetzungssystem R)
112 Freie und gebundene Variablen(vorkommen) Das Vorkommen von v X an Position p in Term t Λ(X) heißt frei, wenn darüber kein λv.... steht Definition (durch strukturelle Induktion): fvar(t) = Menge der in t frei vorkommenden Variablen Eine Variable x heißt in A gebunden, falls A einen Teilausdruck λx.b enthält. bvar(t) = Menge der in t gebundenen Variablen Beispiele: fvar(x(λx.λy.x)) = {x}, bvar(x(λx.λy.x)) = {x, y}
113 Semantik des Lambda-Kalküls Relation β auf Λ(X) (ein Reduktionsschritt) Es gilt t β t, falls p Pos(t), so daß t[p] = (λx.b)a mit bvar(b) fvar(a) = t = t[p := B[x := A]] dabei bezeichnet B[x := A] ein Kopie von B, bei der jedes freie Vorkommen von x durch A ersetzt ist Ein (Teil-)Ausdruck der Form (λx.b)a heißt Redex. (Dort kann weitergerechnet werden.) Ein Term ohne Redex heißt Normalform. (Normalformen sind Resultate von Rechnungen.) Relation α : gebundene Umbenennung
114 Lambda-Terme: verkürzte Notation Applikation als links-assoziativ auffassen, Klammern weglassen: (... ((FA 1 )A 2 )... A n ) FA 1 A 2... A n Beispiel: ((xz)(yz)) xz(yz) geschachtelte Abstraktionen unter ein Lambda schreiben: λx 1.(λx (λx n.b)... ) λx 1 x 2... x n.b Beispiel: λx.λy.λz.b λxyz.b
115 Funktionen höherer Ordnung Funktionen als Argument von Funktionen Beispiel: twice :: (a -> a) -> a -> a twice f x = f (f x) Anwendung: double hat den Typ Int -> Int twice double hat den Typ Int -> Int twice double 3 hat den Typ Int und den Wert? \x -> 2 * x + 1 hat den Typ Int -> Int twice (\x -> 2 * x + 1) hat den Typ Int -> Int twice (\x -> 2 * x + 1) 3 hat den Typ Int und den Wert? succ 0, twice succ 0, twice twice succ 0 twice (^2) 3, twice twice (^2) 3 Typ von twice twice? Typ von twice twice twice?
116 Funktionen höherer Ordnung Beispiele punktweise Summe zweier Funktionen: fsum :: (a -> Int) -> (a -> Int) -> (a -> Int) fsum f g x = (f x) + (g x) fsum f g = \x -> (f x) + (g x) Beispiele: fsum (*2) (+1) 4, fsum len head [ ] Komposition von Funktionen: (.) :: (a -> b) -> (b -> c) -> (a -> c) (f. g) x = f (g x) (f. g) = \ x -> f (g x) Beispiele: ( ( \ x -> x * 2 ). len ) "foo" suchbaum = sortiert. inorder
117 Was bisher geschah Deklarative vs. imperative Programmierung Funktionale Programmierung in Haskell: Algebraische Datentypen Pattern Matching Polymorphie Typklassen Rekursive Datentypen: Peano-Zahlen, Listen, Bäume Rekursive Funktionen strukturelle Induktion Funktionen höherer Ordnung (mit Funktionen als Argumenten) λ-kalkül, β-reduktion
118 Wiederholung: rekursive Datentypen Peano-Zahlen data Nat = Z S Nat Listen data List a = Nil {} Cons { head :: a, tail :: List a} oder kürzer data [a] = [] a : [a] Binärbäume data Tree a = Leaf {} Branch { left :: Tree a, key :: a, right :: Tree a} oder kürzer data Tree a = Leaf Branch ( Tree a ) a ( Tree a )
119 Wiederholung: Funktionen auf rekursiven Datentypen Entwurf rekursiver Funktionen auf rekursiven Datentypen: 1. Typdefinition 2. Angabe aller Basis- und rekursiven Fälle 3. Definition der Ergebnisse der Basisfälle 4. Definition der Ergebnisse der rekursiven Fälle 5. evtl. Typ verallgemeinern Beispiel: Summe aller Schlüssel eines Baumes data Tree a = Leaf Branch (Tree a) a (Tree a) 1. Typdefinition: tsum :: Tree Int -> Int 2. Angabe aller Basis- und rekursiven Fälle: tsum t = case t of Leaf ->... Branch l k r -> Definition der Ergebnisse der Basisfälle: Leaf -> 0 4. Definition der Ergebnisse der rekursiven Fälle: Branch l k r -> (tsum l) + k + (tsum r)
120 Wiederholung: Funktionen auf Listen und Bäumen Operationen auf Listen: Verdoppeln jedes Listenelements Angabe gerade / ungerade für jedes Listenelement Länge der Liste Summe aller Listenelemente Operationen auf Bäumen: Verdoppeln jedes Schlüssels Angabe gerade / ungerade für jeden Schlüssel Anzahl aller Schlüssel Summe aller Schlüssel Inorder-Durchquerung
121 Wiederholung: Funktionen auf Listen Beispiel: Verdoppeln jedes Elementes in einer Liste double :: Int -> Int double x = x + x doubles :: [Int] -> [Int] doubles xs = case xs of [] -> [] (y:ys) -> (double y) : (doubles ys) oder mit anonymer Funktion (λ-notation): doubles :: [Int] -> [Int] doubles xs = case xs of [] -> [] (y:ys) -> ((\ x -> x + x) y) : (doubles ys) evens :: [Int] -> [Bool] evens xs = case xs of [] -> [] (y:ys) -> ((\x->(mod x 2 == 0)) y) : (evens ys)
122 Rekursionsmuster für Listen gemeinsame Eigenschaft: Ergebnis ist die Liste der Funktionswerte jedes Elementes der Eingabeliste Parameter: auf jedes Element anzuwendende Funktion h :: a -> b Liste vom Typ [a] Ergebnis: Liste vom Typ [b] Berechnung (Pattern Matching): f xs = case xs of [] -> [] (x : xss) -> ( h x ) : ( f xss )
123 Rekursionsmuster map Beschreibung des Rekursionsschemas f x = case x of [] -> [] (x : xss) -> ( h x ) : ( f xss ) durch eine Funktion höherer Ordnung mit der Funktion h :: a -> b als Argument map :: ( a -> b ) -> [a] -> [b] Anwendung: f = map h ermöglicht kurze Funktionsdefinition, z.b. doubles :: [ Int ] -> [ Int ] doubles = map double oder mit anonymer Funktion: doubles = map (\z -> z*2) oder noch kürzer: doubles = map ( *2 )
124 filter Beispiel: nur gerade Zahlen der Eingabeliste ev :: Int -> Bool ev = \x -> ( mod x 2 == 0 ) evens :: [Int] -> [Int] evens xs = case xs of [] -> [] ( x : xss ) -> if ev x then x : ( evens xss ) else ( evens xss ) Funktion höherer Ordnung: filter :: ( a -> Bool ) -> [a] -> [a] filter p xs = case xs of [] -> [] ( x : xss ) -> if ( p x ) then x : ( filter p xss ) else filter p xss
125 filter ev :: Int -> Bool ev = \x -> ( mod x 2 == 0 ) filter :: (a -> Bool) -> [a] -> [a] filter p xs = case xs of [] -> [] ( x : xss ) -> if ( p x ) then x : ( filter p xss ) else filter p xss ermöglicht kurze Funktionsdefinitionen, z.b.: evens = filter ev oder mit anonymer Funktion evens = filter ( \x -> ( mod x 2 == 0 ) ) filter ( < 100 ) ( map ( ^2 ) [ 0, ] )
126 Mehr rekursive Funktionen auf Listen data [a] = [] a : [a] Länge einer Liste: len :: [a] -> Int len xs = case xs of [] -> 0 ( _ : xss ) -> 1 + (len xss) Summe aller Listenelemente: sum :: [Int] -> Int sum xs = case xs of [] -> 0 ( x : xss ) -> x + (sum xss)
127 Mehr Rekursionsmuster für Listen gemeinsame Eigenschaft: Parameter: Wert nil :: b für leere Eingabeliste Funktion cons :: a -> b -> b zur Berechnung eines Wertes aus dem bisher berechneten Wert und einem Listenelement Liste vom Typ [a] Ergebnis vom Typ b Berechnung (Pattern Matching): f xs = case xs of [] -> nil (x : xss) -> cons x ( f xss )
128 Rekursionschema fold Funktion höherer Ordnung (mit Funktionen als Argumenten) fold :: b -> (a -> b -> b) -> [a] -> b fold nil cons xs = case xs of [] -> nil x : xss -> cons x ( fold nil cons xss ) ermöglicht kurze Funktionsdefinition, z.b. len = fold 0 (\ x y -> 1 + x) sum = fold 0 (\ x y -> x + y) and = fold True (&&) oder kurz: sum = fold 0 (+)
129 Funktionen höherer Ordnung für Listen in Haskell vordefinierte Funktionen höherer Ordnung zur Verarbeitung von Listen: map :: (a -> b) -> [a] -> [b] foldr :: (a -> b -> b) -> b -> [a] -> b filter :: (a -> Bool) -> [a] -> [a] takewhile :: (a -> Bool) -> [a] -> [a] partition :: (a -> Bool) -> [a] -> ([a],[a]) zum Vergleichen, Ordnen: nubby :: (a -> a -> Bool) -> [a] -> [a] data Ordering = LT EQ GT minimumby :: (a -> a -> Ordering) -> [a] -> a
130 Rekursionsschemata über Bäume data Tree a = Leaf Branch { left :: Tree a, key :: a, right :: Tree a } doubles :: Tree Int -> [Int] doubles t = case t of Leaf -> Leaf Branch l k r -> Branch (doubles l) (k*2) (doubles r) preorder :: Tree a -> [a] preorder t = case t of Leaf -> [] Branch l k r -> [ k ] ++ ( preorder l ) ++ ( preorder r ) sum :: Tree Int -> Int sum t = case t of Leaf -> 0 Branch l k r -> ( sum l ) + k + ( sum r )
131 Rekursionsschema map über Bäume f :: Tree a -> b f t = case t of Leaf -> leaf Branch l k r -> branch (f l) (g k) (f r) Beispiel: f = doubles g = double Rekursionsschema: tmap :: (a -> b ) -> ( Tree a ) -> ( Tree b ) tmap f t = case t of Leaf -> Leaf Branch l k r -> Branch (tmap f l) (f k) (tmap f r) doubles = tmap ( 2* )
132 Rekursionsschema fold über Bäume f :: Tree a -> b f t = case t of Leaf -> leaf Branch l k r -> branch (f l) k (f r) Beispiel: f = preorder leaf = [] branch l k r = [k] ++ l ++ r Rekursionsschema: tfold :: b -> (b -> a -> b -> b) -> (Tree a) -> b tfold leaf branch t = case t of Leaf -> leaf Branch l k r -> branch (tfold leaf branch l) k (tfold leaf branch r)
133 Beispiele: fold über Bäume tfold :: b -> (b -> a -> b -> b) -> (Tree a) -> b tfold leaf branch t = case t of Leaf -> leaf Branch l k r -> branch (tfold leaf branch l) k (tfold leaf branch r) preorder = tfold [] ( \ l k r -> [k] ++ l ++ r ) sum = tfold 0 ( \ l k r -> l + k + r ) analog: Anzahl der Blätter, inneren Knoten, Tiefe
134 Rekursionsmuster (Merksätze) Rekursionsmuster anwenden = jeden Konstruktor durch eine passende Funktion ersetzen Anzahl der Muster-Argumente = Anzahl der Konstruktoren (plus eins für das Datenargument) Stelligkeit eines Muster-Argumentes = Stelligkeit des entsprechenden Konstruktors Rekursion im Typ Rekursion im Muster zu jedem rekursiven Datentyp gibt es genau ein passendes Rekursionsmuster
135 Was bisher geschah Funktionale Programmierung in Haskell: Algebraische Datentypen Pattern Matching Polymorphie Typklassen Rekursive Datentypen: Peano-Zahlen, Listen, Bäume Rekursive Funktionen strukturelle Induktion Rekursionsschemata für Peano-Zahlen, Listen, Bäume Funktionen höherer Ordnung (mit Funktionen als Argumenten) λ-kalkül, β-reduktion fold auf rekursiven Datentypen (Peano-Zahlen, Listen, Bäume) map auf Listen und Bäumen, filter auf Listen
Was bisher geschah. deklarative Programmierung. funktionale Programmierung (Haskell):
Was bisher geschah deklarative Programmierung funktional: Programm: Menge von Termgleichungen, Term Auswertung: Pattern matsching, Termumformungen logisch: Programm: Menge von Regeln (Horn-Formeln), Formel
MehrFormale Methoden in der Informatik Wiederholung klassische Logik Konkrete Datentypen (algebraische Strukturen) Abstrakte Datentypen
Was bisher geschah Formale Methoden in der Informatik Wiederholung klassische Logik Konkrete Datentypen (algebraische Strukturen) Abstrakte Datentypen Syntax: Signatur Semantik: Axiome (FOL-Formeln, meist
MehrHaskell, Typen, und Typberechnung. Grundlagen der Programmierung 3 A. Einige andere Programmiersprachen. Typisierung in Haskell
Haskell, Typen, und Typberechnung Grundlagen der Programmierung 3 A Typen, Typberechnung und Typcheck Prof. Dr. Manfred Schmidt-Schauß Ziele: Haskells Typisierung Typisierungs-Regeln Typ-Berechnung Milners
MehrProgrammieren in Haskell Programmiermethodik
Programmieren in Haskell Programmiermethodik Peter Steffen Universität Bielefeld Technische Fakultät 12.01.2011 1 Programmieren in Haskell Bisherige Themen Was soll wiederholt werden? Bedienung von hugs
MehrFrage, Fragen und nochmals Fragen
Frage, Fragen und nochmals Fragen Berthold Hoffmann Universität Bremen and DFKI Bremen hof@informatik.uni-bremen.de In diesem Text stehen einige Fragen, die man sich zu den Folien der Veranstaltung Funktionales
MehrProgrammieren in Haskell
Programmieren in Haskell Wir steigen ein... Programmieren in Haskell 1 Was wir heute machen Umfrage: Wer hat den Hugs ausprobiert? Ausdrücke und Werte Datentypen Funktionen Aufgabe für diese Woche Programmieren
MehrZahlen in Haskell Kapitel 3
Einführung in die Funktionale Programmiersprache Haskell Zahlen in Haskell Kapitel 3 FH Wedel IT-Seminar: WS 2003/04 Dozent: Prof. Dr. Schmidt Autor: Timo Wlecke (wi3309) Vortrag am: 04.11.2003 - Kapitel
MehrTutorium - Haskell in der Schule. Ralf Dorn - Dennis Buchmann - Felix Last - Carl Ambroselli
Tutorium - Haskell in der Schule Wer sind wir? Otto-Nagel-Gymnasium in Berlin-Biesdorf Hochbegabtenförderung und MacBook-Schule Leistungskurse seit 2005 Einführung Was ist funktionale Programmierung? Einführung
MehrFunktionale Programmierung mit Haskell
Funktionale Programmierung mit Haskell Dr. Michael Savorić Hohenstaufen-Gymnasium (HSG) Kaiserslautern Version 20120622 Überblick Wichtige Eigenschaften Einführungsbeispiele Listenerzeugung und Beispiel
MehrFunktionale Programmiersprachen
Funktionale Programmiersprachen An den Beispielen Haskell und Erlang Übersicht Programmiersprachen λ-kalkül Syntax, Definitionen Besonderheiten von funktionalen Programmiersprache, bzw. Haskell Objektorientierte
MehrWiederholung ADT Menge Ziel: Verwaltung (Finden, Einfügen, Entfernen) einer Menge von Elementen
Was bisher geschah abstrakter Datentyp : Signatur Σ und Axiome Φ z.b. ADT Menge zur Verwaltung (Finden, Einfügen, Entfernen) mehrerer Elemente desselben Typs Spezifikation einer Schnittstelle Konkreter
MehrBeispiele: (Funktionen auf Listen) (3) Bemerkungen: Die Datenstrukturen der Paare (2) Die Datenstrukturen der Paare
Beispiele: (Funktionen auf Listen) (3) Bemerkungen: 5. Zusammenhängen der Elemente einer Liste von Listen: concat :: [[a]] -> [a] concat xl = if null xl then [] else append (head xl) ( concat (tail xl))
Mehrexpr :: Expr expr = Mul (Add (Const 3) (Const 4)) (Div (Sub (Const 73) (Const 37)) (Const 6))
1 - Korrektur 2 - Abstrakte Datentypen für arithmetische Ausdrücke Der Datentyp Wir beginnen zunächst mit dem algebraischen Datentyp für Ausdrücke. Hierfür definieren wir einen Konstruktor Number für Zahlen,
MehrFunktionale Programmierung mit Haskell. Jan Hermanns
Funktionale Programmierung mit Haskell Jan Hermanns 1 Programmiersprachen imperativ deklarativ konventionell OO logisch funktional Fortran Smalltalk Prolog Lisp C Eiffel ML Pascal Java Haskell 2 von Neumann
MehrFunktionale Programmierung
Funktionale Programmierung Jörg Kreiker Uni Kassel und SMA Solar Technology AG Wintersemester 2011/2012 2 Teil II Typen mit Werten und Ausdruck, sogar listenweise 3 Haskell Programme Programm Module ein
MehrGrundprinzipien der funktionalen Programmierung
Grundprinzipien der funktionalen Programmierung Funktionen haben keine Seiteneffekte Eine Funktion berechnet einen Ausgabewert der nur von den Eingabewerten abhängt: 12 inputs + output 46 34 2 Nicht nur
MehrTag 7. Pattern Matching und eigene Datentypen
Tag 7 Pattern Matching und eigene Datentypen Heute werden wir eine Technik kennenlernen, die dafür sorgt, daß wir sehr viel übersichtlichere und kürzere Programme schreiben können. Als Überleitung auf
MehrWas bisher geschah Funktionale Programmierung in Haskell: Algebraische Datentypen Pattern Matching Polymorphie Typklassen Rekursive Datentypen:
Was bisher geschah Funktionale Programmierung in Haskell: Algebraische Datentypen Pattern Matching Polymorphie Typklassen Rekursive Datentypen: Peano-Zahlen, Listen, Bäume Rekursive Funktionen strukturelle
MehrProgrammieren in Haskell
Programmieren in Haskell Syntax und Semantik von Haskell Programmieren in Haskell 1 Was wir heute (und nächstes mal) machen Datentypdefinitionen Wertdefinitionen, Variablenbindungen Musterbindungen Funktionsbindungen
MehrStrukturelle Rekursion und Induktion
Kapitel 2 Strukturelle Rekursion und Induktion Rekursion ist eine konstruktive Technik für die Beschreibung unendlicher Mengen (und damit insbesondere für die Beschreibung unendliche Funktionen). Induktion
MehrWS 2011/2012. Georg Sauthoff 1. October 18, 2011
in in WS 2011/2012 Georg 1 AG Praktische Informatik October 18, 2011 1 gsauthof@techfak.uni-bielefeld.de Neue Übungsgruppen in neue Übungsgruppen neue Tutoren Sprechstunden in GZI-Arbeitsraum (V2-240)
MehrSoftwaretechnik. Funktionale Programmierung. Christian Lindig. 23. Januar 2006. Lehrstuhl für Softwaretechnik Universität des Saarlandes
Softwaretechnik Funktionale Programmierung Christian Lindig Lehrstuhl für Softwaretechnik Universität des Saarlandes 23. Januar 2006 Quicksort in Java static void sort(int a[], int lo0, int hi0) { int
MehrFunktionale Programmierung ALP I. Funktionen höherer Ordnung. Teil 2 SS 2013. Prof. Dr. Margarita Esponda. Prof. Dr.
ALP I Funktionen höherer Ordnung Teil 2 SS 2013 Funktionen höherer Ordnung Nehmen wir an, wir möchten alle Zahlen innerhalb einer Liste miteinander addieren addall:: (Num a) => [a -> a addall [ = 0 addall
MehrEinführung in die Programmierung mit VBA
Einführung in die Programmierung mit VBA Vorlesung vom 07. November 2016 Birger Krägelin Inhalt Vom Algorithmus zum Programm Programmiersprachen Programmieren mit VBA in Excel Datentypen und Variablen
MehrProgrammieren in Haskell Einführung
Programmieren in Haskell Einführung Peter Steffen Universität Bielefeld Technische Fakultät 16.10.2009 1 Programmieren in Haskell Veranstalter Dr. Peter Steffen Raum: M3-124 Tel.: 0521/106-2906 Email:
MehrProgrammierung und Modellierung
Programmierung und Modellierung Terme, Suchbäume und Pattern Matching Martin Wirsing in Zusammenarbeit mit Moritz Hammer SS 2009 2 Inhalt Kap. 7 Benutzerdefinierte Datentypen 7. Binärer Suchbaum 8. Anwendung:
MehrCrashkurs Haskell Mentoring WiSe 2016/17. Anja Wolffgramm Freie Universität Berlin
Crashkurs Haskell Mentoring WiSe 2016/17 Anja Wolffgramm Freie Universität Berlin 02/11/2016 , Inhalt Kommandozeile Haskell installieren & starten Ein 1. Haskell-Programm Funktionsdefinition Primitive
MehrPraktische Informatik 3: Einführung in die Funktionale Programmierung Vorlesung vom 10.11.2010: Rekursive Datentypen
Rev. 1152 1 [23] Praktische Informatik 3: Einführung in die Funktionale Programmierung Vorlesung vom 10.11.2010: Rekursive Datentypen Christoph Lüth & Dennis Walter Universität Bremen Wintersemester 2010/11
MehrVorlesung Datenstrukturen
Vorlesung Datenstrukturen Binärbaum Suchbaum Dr. Frank Seifert Vorlesung Datenstrukturen - Sommersemester 2016 Folie 356 Datenstruktur Binärbaum Strukturrepräsentation des mathematischen Konzepts Binärbaum
Mehrzu große Programme (Bildschirmseite!) zerlegen in (weitgehend) unabhängige Einheiten: Unterprogramme
Bisher Datentypen: einfach Zahlen, Wahrheitswerte, Zeichenketten zusammengesetzt Arrays (Felder) zur Verwaltung mehrerer zusammengehörender Daten desselben Datentypes eindimensional, mehrdimensional, Array-Grenzen
MehrAllgemeine Hinweise: TECHNISCHE UNIVERSITÄT MÜNCHEN. Name Vorname Studiengang Matrikelnummer. Hörsaal Reihe Sitzplatz Unterschrift
TECHNISCHE UNIVERSITÄT MÜNCHEN FAKULTÄT FÜR INFORMATIK Lehrstuhl für Sprachen und Beschreibungsstrukturen WS 2008/09 Einführung in die Informatik 2 Klausur Prof. Dr. Helmut Seidl, T. M. Gawlitza, S. Pott,
MehrWS 2011/2012. Georg Sauthoff 1. November 1, 2011
WS 2011/2012 Georg 1 AG Praktische Informatik November 1, 2011 1 gsauthof@techfak.uni-bielefeld.de Übungen Abgaben und Aufgabenblätter am Ende der Vorlesung Skript gibt es demnächst in den Übungen Der
MehrDer λ-kalkül. Frank Huch. Sommersemester 2015
Der λ-kalkül Frank Huch Sommersemester 2015 In diesem Skript werden die Grundlagen der Funktionalen Programmierung, insbesondere der λ-kalkül eingeführt. Der hier präsentierte Stoff stellt einen teil der
MehrFunktionale Programmierung
FP-1.0 Funktionale Programmierung Prof. Dr. Uwe Kastens SS 2013 Vorlesung Funktionale Programmierung SS 2013 / Folie 100 Begrüßung Functional Programming is Fun FP-1.1 Fun ctional Programming is Fun ctional
Mehrzu große Programme (Bildschirmseite!) zerlegen in (weitgehend) unabhängige Einheiten: Unterprogramme
Bisher Datentypen: einfach Zahlen, Wahrheitswerte, Zeichenketten zusammengesetzt Arrays (Felder) zur Verwaltung mehrerer zusammengehörender Daten desselben Datentypes eindimensional, mehrdimensional, Array-Grenzen
MehrTheoretische Grundlagen des Software Engineering
Theoretische Grundlagen des Software Engineering 12: Termersetzungssysteme schulz@eprover.org Reduktionssysteme Definition: Reduktionssystem Ein Reduktionssystem ist ein Tupel (A, ) Dabei gilt: A ist eine
MehrFunktionale Programmierung
Schleifen 1 Funktionale Programmierung Jörg Kreiker Uni Kassel und SMA Solar Technology AG Wintersemester 2011/2012 3 Teil I Jedem Anfang wohnt ein Zauber inne 4 Über mich Diplom in Informatik in Saarbrücken
Mehr4.Grundsätzliche Programmentwicklungsmethoden
4.Grundsätzliche Programmentwicklungsmethoden 1.1 Grundlage strukturierter und objektorientierter Programmierung Begriff Software Engineering - umfaßt den gezielten Einsatz von Beschreibungsmitteln, Methoden
MehrProgrammieren in Haskell
Programmieren in Haskell Felder (Arrays) Programmieren in Haskell 1 Was wir heute machen Motivationsbeispiel Die Typklasse Ix Felder in Haskell Funktionstabellierung Binäre Suche Pascalsches Dreieck Ein
MehrTypdeklarationen. Es gibt in Haskell bereits primitive Typen:
Typdeklarationen Es gibt in bereits primitive Typen: Integer: ganze Zahlen, z.b. 1289736781236 Int: ganze Zahlen mit Computerarithmetik, z.b. 123 Double: Fließkommazahlen, z.b. 3.14159 String: Zeichenketten,
MehrEine zu Grunde liegende Typdefinition beschreibt eine Struktur, die alle erlaubten Instanzen dieses Typs gemeinsam haben.
Der binäre Baum Tree Die geläufigste Datenstuktur ist der binäre Baum Tree. Dieses Beispielskript zeigt im direkten Vergleich zu anderen Sprachen den Umgang mit formalen Typparametern in CHELSEA. Wir steigen
MehrFunktionale Programmierung Teil 2 Methodik: Spezifikation, Implementierung, Verifikation
Grundlagen der Programm- und Systementwicklung Funktionale Programmierung Teil 2 Methodik: Spezifikation, Implementierung, Verifikation Technische Universität München Institut für Informatik Software &
MehrALP I Einführung in Haskell
ALP I Einführung in Haskell WS 2012/2013 Was ist Haskell? Haskell ist eine rein Funktionale Programmiersprache mit einer nach Bedarf Auswertung-Strategie oder "Lazy Evaluation". Was bedeutet rein funktional?
MehrGrundlagen der Theoretischen Informatik
Grundlagen der Theoretischen Informatik Sommersemester 2015 23.04.2015 Viorica Sofronie-Stokkermans e-mail: sofronie@uni-koblenz.de 1 Bis jetzt 1. Terminologie 2. Endliche Automaten und reguläre Sprachen
MehrKapitel 7: Benutzerdefinierte Datentypen
Kapitel 7: Benutzerdefinierte Datentypen Andreas Abel LFE Theoretische Informatik Institut für Informatik Ludwig-Maximilians-Universität München 10. Juni 2011 Quelle: Martin Wirsing, Benutzerdefinierte
MehrInferenzmethoden. Einheit 18. Logik höherer Stufe
Inferenzmethoden Einheit 18 Logik höherer Stufe 1. Syntax und Semantik 2. Simulation mathematischer Konstrukte 3. Beweisführung in Logik höherer Stufe Logik höherer Stufe Logik erster Stufe hat nur einfache
MehrDiskrete Strukturen Kapitel 2: Grundlagen (Relationen)
WS 2016/17 Diskrete Strukturen Kapitel 2: Grundlagen (Relationen) Hans-Joachim Bungartz Lehrstuhl für wissenschaftliches Rechnen Fakultät für Informatik Technische Universität München http://www5.in.tum.de/wiki/index.php/diskrete_strukturen_-_winter_16
MehrAgenda. 1 Einleitung. 2 Binäre Bäume. 3 Binäre Suchbäume. 4 Rose Trees. 5 Zusammenfassung & Ausblick. Haskell Bäume. Einleitung.
Vortrag: Bäume in Haskell Bäume in Haskell Vortrag Christoph Forster Thomas Kresalek Fachhochschule Wedel University of Applied Sciences 27. November 2009 Christoph Forster, Thomas Kresalek 1/53 Vortrag
MehrProgrammiersprachen. Organisation und Einführung. Berthold Hoffmann. Studiengang Informatik Universität Bremen
Organisation und Einführung Studiengang Informatik Universität Bremen Sommersemester 2010 (Vorlesung am Montag, der 12. April 2010) (Montag, der 12. April 2008) 1 Vorstellung 2 Organisation 3 Einführung
MehrHaskell. A Wild Ride. Sven M. Hallberg. sm@khjk.org. 21C3 Berlin / Bildungswerk Hamburg 20.6.2007 p. 1/36
21C3 Berlin / Bildungswerk Hamburg 20.6.2007 p. 1/36 Haskell A Wild Ride Sven M. Hallberg sm@khjk.org 21C3 Berlin / Bildungswerk Hamburg 20.6.2007 p. 2/36 Überblick Vorsichtsmaßnahmen Einführung und Sprachgrundlagen
MehrFunktionen höherer Ordnung
Eine Funktion wird als Funktion höherer Ordnung bezeichnet, wenn Funktionen als Argumente verwendet werden, oder wenn eine Funktion als Ergebnis zurück gegeben wird. Beispiel: twotimes :: ( a -> a ) ->
MehrTutoraufgabe 1 (Datenstrukturen in Haskell):
Prof. aa Dr. J. Giesl Programmierung WS12/13 M. Brockschmidt, F. Emmes, C. Otto, T. Ströder Allgemeine Die Hausaufgaben sollen in Gruppen von je 2 Studierenden aus der gleichen Kleingruppenübung (Tutorium)
MehrFunktionale Programmierung mit Haskell
Funktionale Programmierung mit Haskell Prof. Dr. Hans J. Schneider Lehrstuhl für Programmiersprachen und Programmiermethodik Friedrich-Alexander-Universität Erlangen-Nürnberg Sommersemester 2011 I. Die
Mehr2.5 Listen. Kurzschreibweise: [42; 0; 16] Listen werden mithilfe von [] und :: konstruiert.
2.5 Listen Listen werden mithilfe von [] und :: konstruiert. Kurzschreibweise: [42; 0; 16] # let mt = [];; val mt : a list = [] # let l1 = 1::mt;; val l1 : int list = [1] # let l = [1;2;3];; val l : int
MehrGenerische Record-Kombinatoren mit statischer Typprüfung
System Generische mit statischer Typprüfung Brandenburgische Technische Universität Cottbus Lehrstuhl Programmiersprachen und Compilerbau Lehrstuhlkolloquium am 13. Januar 2010 Überblick System System
MehrGrundlagen der Programmierung 2. Bäume
Grundlagen der Programmierung 2 Bäume Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie 24. Mai 2006 Graphen Graph: Menge von Knoten undzugehörige (gerichtete oder ungerichtete)
MehrPraktische Informatik 3: Funktionale Programmierung Vorlesung 3 vom : Algebraische Datentypen
16:01:59 2017-01-17 1 [35] Praktische Informatik 3: Funktionale Programmierung Vorlesung 3 vom 01.11.2016: Algebraische Datentypen Christoph Lüth Universität Bremen Wintersemester 2016/17 PI3 WS 16/17
Mehr11 Fallstudie: Reguläre Ausdrücke
11 Fallstudie: Reguläre Ausdrücke Mit den bisher eingeführten Sprachelementen von Haskell lassen sich bereits substantielle Projekte realisieren. Dieses Kapitel 1 beschreibt einen algebraischen Datentyp
Mehr26 Hierarchisch strukturierte Daten
Algorithmik II Peter Wilke Sommersemester 2005 Teil III Funktionale Programmierung 26 Hierarchisch strukturierte Daten Peter Wilke Algorithmik II Sommersemester 2005 1 Peter Wilke Algorithmik II Sommersemester
MehrTheoretische Informatik II
Vorlesung Theoretische Informatik II Bernhard Beckert Institut für Informatik Wintersemester 2007/2008 B. Beckert Theoretischen Informatik II: WS 2007/08 1 / 179 Dank Diese Vorlesungsmaterialien basieren
MehrKapitel 5: Applikative Programmierung
Kapitel 5: Applikative Programmierung In der applikativen Programmierung wird ein Programm als eine mathematische Funktion von Eingabe-in Ausgabewerte betrachtet. Das Ausführen eines Programms besteht
MehrGrundlagen der Programmierung 2 (1.C)
Grundlagen der Programmierung 2 (1.C) Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie 3. Mai 2006 Funktionen auf Listen: map map :: (a -> b) -> [a] -> [b] map f [] = []
MehrGrundlagen der Mathematik
Grundlagen der Mathematik Übungsaufgaben zu Kapitel 1 Einführung 1.1.1 Für reelle Zahlen a und b gilt (a+b) (a-b) = a 2 -b 2. Was ist die Voraussetzung? Wie lautet die Behauptung? Beweisen Sie die Behauptung.
MehrDATENSTRUKTUREN UND ZAHLENSYSTEME
DATENSTRUKTUREN UND ZAHLENSYSTEME RALF HINZE Institute of Information and Computing Sciences Utrecht University Email: ralf@cs.uu.nl Homepage: http://www.cs.uu.nl/~ralf/ March, 2001 (Die Folien finden
MehrEscher funktionale und logische Programmierung
Escher funktionale und logische Programmierung Seminar Programming Languages From Hell Lars Hupel 2010-06-07 Dieses Werk ist lizenziert unter den Bedingungen der Creative Commons Namensnennung 3.0 Deutschland.
MehrMengen. Eigenschaften. Spezielle Mengen (1) Prominente Mengen. ! Mengenzugehörigkeit
Mengen! Definition (Intuitive Mengenlehre) Eine Menge ist die Zusammenfassung von Elementen unserer Anschauung zu einem wohldefinierten Ganzen. (Georg Cantor)! Notation 1. Aufzählung aller Elemente: {
MehrHaskell zur Constraint-Programmierung HaL8
Haskell zur Constraint-Programmierung HaL8 Alexander Bau 2. Mai 2013 Wir benutzen eine Teilmenge von Haskell zur Spezifikation von Constraint- Systemen über Haskell-Datentypen. Ein Constraint-Compiler
MehrLogik-Grundlagen. Syntax der Prädikatenlogik
Logik-Grundlagen X 1 :...: X k : ( A 1 A 2... A m B 1 B 2... B n ) Logische und funktionale Programmierung - Universität Potsdam - M. Thomas - Prädikatenlogik III.1 Syntax der Prädikatenlogik Prädikat:
Mehr5 Logische Programmierung
5 Logische Programmierung Logik wird als Programmiersprache benutzt Der logische Ansatz zu Programmierung ist (sowie der funktionale) deklarativ; Programme können mit Hilfe zweier abstrakten, maschinen-unabhängigen
MehrC.3 Funktionen und Prozeduren
C3 - Funktionen und Prozeduren Funktionsdeklarationen in Pascal auch in Pascal kann man selbstdefinierte Funktionen einführen: Funktionen und Prozeduren THEN sign:= 0 Funktion zur Bestimmung des Vorzeichens
MehrProgrammierung 1 - Repetitorium
WS 2002/2003 Programmierung 1 - Repetitorium Andreas Augustin und Marc Wagner Homepage: http://info1.marcwagner.info Donnerstag, den 10.04.03 Kapitel 7 Korrektheit 7.1 Abstrakte Prozeduren Abstrakte Prozedur
MehrALP I. Funktionale Programmierung
ALP I Funktionale Programmierung Sortieren und Suchen (Teil 1) WS 2012/2013 Suchen 8 False unsortiert 21 4 16 7 19 11 12 7 1 5 27 3 8 False sortiert 2 4 6 7 9 11 12 18 21 24 27 36 Suchen in unsortierten
MehrFunktionale Programmierung mit C++
Funktionale Programmierung mit C++ Rainer Grimm Softwarearchitekt Partner: Überblick Programmierung in funktionaler Art Warum funktionale Programmierung? Was ist funktionale Programmierung? Charakteristiken
Mehr4. Jeder Knoten hat höchstens zwei Kinder, ein linkes und ein rechtes.
Binäre Bäume Definition: Ein binärer Baum T besteht aus einer Menge von Knoten, die durch eine Vater-Kind-Beziehung wie folgt strukturiert ist: 1. Es gibt genau einen hervorgehobenen Knoten r T, die Wurzel
MehrImperative vs. Funktionale Programmierung
Beispiel: Entwerfe eine Funktion, die testet, ob eine Zahl n eine Primzahl ist oder nicht. Beobachtung: (1) Wenn n Primzahl ist, ist die Menge der Teiler von n leer. (2) Die Menge der Teiler von n sind
Mehr6.1 Natürliche Zahlen 6.2 Induktion und Rekursion 6.3 Ganze, rationale, reelle und komplexe Zahlen 6.4 Darstellung von Zahlen
6. Zahlen 6.1 Natürliche Zahlen 6.2 Induktion und Rekursion 6.3 Ganze, rationale, reelle und komplexe Zahlen 6.4 Darstellung von Zahlen 6. Zahlen GM 6-1 6.1 Natürliche Zahlen Vom lieben Gott gemacht Menschenwerk:
MehrVBA-Programmierung: Zusammenfassung
VBA-Programmierung: Zusammenfassung Programmiersprachen (Definition, Einordnung VBA) Softwareentwicklung-Phasen: 1. Spezifikation 2. Entwurf 3. Implementierung Datentypen (einfach, zusammengesetzt) Programmablaufsteuerung
MehrInduktive Definitionen
Induktive Definitionen Induktive Definition: Konstruktive Methode zur Definition einer Menge M von Objekten aus Basisobjekten mittels (Erzeugungs-) Regeln Slide 1 Rekursion über den Aufbau: Konstruktive
MehrProf. Dr. Uwe Schmidt. 12. August Aufgaben zur Klausur Softwaredesign im SS 2014 (BInf v310, BMInf v300, BWInf v310, BWInf- 23)
Prof. Dr. Uwe Schmidt 12. August 2014 Aufgaben zur Klausur Softwaredesign im SS 2014 (BInf v310, BMInf v300, BWInf v310, BWInf- 23) Zeit: 90 Minuten erlaubte Hilfsmittel: keine Bitte tragen Sie Ihre Antworten
MehrGrundlagen der Programmierung in C Funktionen
Der erste Mechanismus für Code-Reuse! Grundlagen der Programmierung in C Funktionen Wintersemester 2005/2006 G. Zachmann Clausthal University, Germany zach@in.tu-clausthal.de Ältester Mechanismus für Code-Reuse:
MehrWissensbasierte Systeme
WBS4 Slide 1 Wissensbasierte Systeme Vorlesung 4 vom 03.11.2004 Sebastian Iwanowski FH Wedel WBS4 Slide 2 Wissensbasierte Systeme 1. Motivation 2. Prinzipien und Anwendungen 3. Logische Grundlagen 4. Suchstrategien
MehrInhaltsverzeichnis. Einführende Bemerkungen 11. Das Fach Informatik 11 Zielsetzung der Vorlesung Grundbegriffe
Inhaltsverzeichnis Einführende Bemerkungen 11 Das Fach Informatik 11 Zielsetzung der Vorlesung 12 1. Grundbegriffe 1 3 1.1 1.2 1.3 1.4 1.5 1.6 1.7 Information und Nachricht 1.1.1 Information 1.1.2 Nachricht
MehrAlgorithmen & Programmierung. Ausdrücke & Operatoren (1)
Algorithmen & Programmierung Ausdrücke & Operatoren (1) Ausdrücke Was ist ein Ausdruck? Literal Variable Funktionsaufruf Ausdruck, der durch Anwendung eines einstelligen (unären) Operators auf einen Ausdruck
Mehr1. Der Begriff Informatik 2. Syntax und Semantik von Programmiersprachen. I.2. I.2. Grundlagen von von Programmiersprachen.
1. Der Begriff Informatik 2. Syntax und Semantik von Programmiersprachen I.2. I.2. Grundlagen von von Programmiersprachen. - 1 - 1. Der Begriff Informatik "Informatik" = Kunstwort aus Information und Mathematik
MehrFunktionale Programmierung mit C++
Funktionale Programmierung mit C++ Überblick Programmierung in funktionaler Art Warum funktionale Programmierung? Was ist funktionale Programmierung? Charakteristiken funktionaler Programmierung Was fehlt
MehrVorsicht bei redundanten und unvollständigen Matches!
Vorsicht bei redundanten und unvollständigen Matches! # let n = 7;; val n : int = 7 # match n with 0 -> "null";; Warning: this pattern-matching is not exhaustive. Here is an example of a value that is
MehrProseminar: Perlen der Informatik II Haskell List comprehensions & Typklassen
Proseminar: Perlen der Informatik II Haskell List comprehensions & Typklassen Dmitriy Traytel 8. Juli 2008 Diese Ausarbeitung im Rahmen des Proseminars Perlen der Informatik II beschäftigt sich mit einigen
MehrÜbersicht. Datenstrukturen und Algorithmen Vorlesung 5: Rekursionsgleichungen (K4) Übersicht. Binäre Suche. Joost-Pieter Katoen. 20.
Übersicht Datenstrukturen und Algorithmen Vorlesung 5: (K4) Joost-Pieter Katoen Lehrstuhl für Informatik 2 Software Modeling and Verification Group http://www-i2.informatik.rwth-aachen.de/i2/dsal12/ 20.
MehrSprachen und Programmiersprachen
Sprachen und Programmiersprachen Natürliche Sprachen versus Programmiersprachen / Spezifikationssprachen Syntax legt die grammatikalische Korrektheit fest. Semantik legt die Bedeutung von syntaktisch korrekten
MehrSWP Prüfungsvorbereitung
20. Juni 2011 1 Grammatiken 2 LL(1) 3 EXP 4 Datentypen 5 LP Grammatiken Angabe Erstellen Sie First- und Follow-Mengen aller Non-Terminale der folgenden Grammatik. S a S S B y B A C A A b b A x A ɛ C c
MehrFunktionale Programmierung mit Haskell
Funktionale Programmierung mit Haskell Prof. Dr. Hans J. Schneider Lehrstuhl für Programmiersprachen und Programmiermethodik Friedrich-Alexander-Universität Erlangen-Nürnberg Sommersemester 2011 I. Die
MehrWerkzeuge zur Programmentwicklung
Werkzeuge zur Programmentwicklung B-15 Bibliothek Modulschnittstellen vorübersetzte Module Eingabe Editor Übersetzer (Compiler) Binder (Linker) Rechner mit Systemsoftware Quellmodul (Source) Zielmodul
MehrRepetitorium Informatik (Java)
Repetitorium Informatik (Java) Tag 6 Lehrstuhl für Informatik 2 (Programmiersysteme) Übersicht 1 Klassen und Objekte Objektorientierung Begrifflichkeiten Deklaration von Klassen Instanzmethoden/-variablen
Mehr4: Algebraische Strukturen / Gruppen
Stefan Lucks Diskrete Strukturen (WS 2009/10) 120 4: Algebraische Strukturen / Gruppen Definition 46 Sei G eine nichtleere Menge. Eine Funktion : G G G bezeichnen wir als Verknüpfung auf G. Das Paar (G,
MehrVorsemesterkurs Informatik
Stand der Folien: 31. März 2011 Vorsemesterkurs Informatik Sommersemester 2011 Grundlagen der Programmierung in Haskell SoSe 2011 Übersicht 1 Ausdrücke und Typen 2 Funktionen 3 Rekursion 4 Listen 5 Paare
MehrBrückenkurs Mathematik
Brückenkurs Mathematik 6.10. - 17.10. Vorlesung 1 Logik,, Doris Bohnet Universität Hamburg - Department Mathematik Mo 6.10.2008 Zeitplan Tagesablauf: 9:15-11:45 Vorlesung Audimax I 13:00-14:30 Übung Übungsräume
Mehr6. Induktives Beweisen - Themenübersicht
6. Induktives Beweisen - Themenübersicht Ordnungsrelationen Partielle Ordnungen Quasiordnungen Totale Ordnungen Striktordnungen Ordnungen und Teilstrukturen Noethersche Induktion Anwendung: Terminierungsbeweise
MehrVerträge für die funktionale Programmierung Design und Implementierung
1 Verträge für die funktionale Programmierung Design und Implementierung RALF HINZE Institut für Informatik III, Universität Bonn Römerstraße 164, 53117 Bonn, Germany Email: ralf@informatik.uni-bonn.de
MehrBinärbäume als weiteres Beispiel für abstrakte Datentypen in PVS mit in Knoten gespeicherten Werten vom Typ T:
Binäre Bäume Binärbäume als weiteres Beispiel für abstrakte Datentypen in PVS mit in Knoten gespeicherten Werten vom Typ T: BinTree [T: TYPE]: DATATYPE empty: empty? node (key: T, left:bibtree, right:bibtree):
MehrWas bisher geschah ADT Menge mit Operationen: Suche nach einem Element Einfügen eines Elementes Löschen eines Elementes Realisierung durch
Was bisher geschah ADT Menge mit Operationen: Suche nach einem Element Einfügen eines Elementes Löschen eines Elementes Realisierung durch verschiedene Datenstrukturen: lineare Datenstrukturen: Array,
Mehr