Einführung

Werbung
Grundprinzipien der
funktionalen
Programmierung
Funktionen haben keine Seiteneffekte
Eine Funktion berechnet einen Ausgabewert der nur
von den Eingabewerten abhängt:
12
34
inputs
+
output
46
2
Nicht nur Zahlen, auch Bilder
A function to flip a picture in a vertical mirror:
input
output
flipV
3
Mehr Funktionen auf Bildern
A function to invert the colours in a picture:
invertColour
4
Mehr Funktionen auf Bildern
A function to superimpose two pictures:
superimpose
5
Mehr Funktionen auf Bildern
A function to put one picture above another:
above
6
Mehr Funktionen auf Bildern
A function to put two pictures side by side:
sideBySide
7
Typen
Ein Typ ist eine Menge von Werten, wie Zahlen oder
Bilder.
Auf alle Werte eines Typs sind die gleichen
Funktionen anwendbar:
Wir können zwei Zahlen addieren, nicht aber eine
Zahl und ein Bild oder zwei Bilder.
8
Alles hat einen Typ
Werte haben Typen:
true : bool
1 : int
Funktionen haben Typen:
+ : int -> int -> int
above: picture -> picture -> picture
9
Klammerung von Typen
Implizite Klammerung:
T1 -> T2 -> T = T1 -> (T2 -> T)
+ : int -> int -> int
+ : (int -> int) -> int
integrate: (real -> real) -> real -> real
-> real
integrate: real -> real -> real -> real
-> real
10
Auswertung von Ausdrücken durch
Termersetzung
(7-3)+ 2
Ausdruck
(7-3)+ 2
4+2
Wert
Auswertung
4+2
6
11
sideBySide
(invertColour
)
sideBySide
Auswertung
mit Bildern
12
Auswertungsstrategien
f x = 1
g x = g x
Eager evaluation / Call-by-value / Eifrige
Auswertung: f(g 1) => f(g 1) => ...
Prinzip: Zuerst die Parameter, dann die Funktion
Lazy evaluation / Call-by-need / Verzögerte
Auswertung: f(g 1) => 1
Prinzip: Parameter erst, wenn sie gebraucht werden
13
Auswertungsstrategien
Wenn eifrige Auswertung terminiert, dann auch
verzögerte Auswertung, und beide berechnen den
gleichen Wert.
SML: Eager evaluation
Haskell: Lazy evaluation
14
Ausdrücke (Terme)
Ein Ausdruck ist entweder atomar (z.B. x, true, 42)
oder zusammengesetzt: f a1 ... an
wobei f, a1,..., an Ausdrücke passenden Typs sind:
f : T1 -> ... -> Tn -> T
ai : Ti
15
Klammerung von Ausdrücken
Implizite Klammerung: f a b = (f a) b
Funktionsanwendung ist nach links geklammert
sin cos pi = (sin cos) pi
sin(cos pi)
integrate sin pi = (integrate sin) pi
integrate (sin pi)
16
Präfix und Infix
Infix: 3+4 ist Abkürzung für + 3 4
Präfix bindet stärker als Infix:
f x+1 = (f x) + 1
17
Funktionale
Programmierung
in SML
The Web page
...
SML distributions and documentation.
Background material: books, FAQs, etc
...
19
Wertedefinitionen in SML
Allgemeines Format:
val name = expression
Beispiele:
val null = 0+0;
val Horse = above horse horse;
20
Funktionsdefinitionen in SML
Einfaches Format:
fun name x1 ... xn = expression
Beispiel:
fun sum n =
if n=0 then 0 else n+sum(n-1);
21
Funktionsdefinitionen in SML
Mit Pattern Matching:
fun name pat ... pat = expression
| name pat ... pat = expression
...
Beispiel:
fun sum 0 = 0
| sum n = n + sum(n-1)
Reihenfolge der Gleichungen wichtig!
22
Lokale Definitionen: let
let val x = 42 in x+x end
=> 42+42
=> 84
let fun f x = x+1 in f(f 5) end
... => 7
23
Typen in SML
Typinferenz
SML berechnet automatisch den Typ jedes
Ausdrucks
val x = 42;
> ... : int
fun f x = x+1;
> ... : int -> int
25
Polymorphismus
Der Typ einer Funktion kann Typvariablen
enthalten: ’a, ’b, ’name
Ein solcher Typ heisst polymorph.
fun f x = x;
>
f
>
f
>
... : ’a -> ’a
5;
5 : int
true;
true : bool
26
Polymorphismus
fun S x y z = (x z) (y z);
Was ist der Typ der Funktion?
Typinferenz berechnet den allgemeinsten
Typ.
Polymorphismus ist ein Abstraktionsprinzip.
27
Basistypen
•bool
•int, real
•char, string
28
Booleans
Everything is true or false
29
Vordefinierte Boolesche Operatoren
if x:bool then y:T else z:T
a andalso b
a orelse b
not a
= if a then b else false
= if a then true else b
= if a then false else true
30
Beispiel Pattern Matching
fun
|
|
|
xor
xor
xor
xor
true true = false
false true = true
true false = true
false false = false;
31
Arithmetik: int und real
42 : int
42.0 : real
Funktionen: ~ + - * /
Vergleiche: < <= > >=
div mod ...
Infix syntax: 3 + 4
Präfix syntax: op + (3,4)
op + : int * int -> int
32
Überladung
Die meisten vordefinierten Operatoren (+, ..., <, ...)
sind überladen, dh sowohl für int als auch real
definiert.
Benutzerdefinierte Funktionen dürfen nicht
überladen sein:
fun doppel x = x+x;
> Fehlermeldung wg Überladung
fun doppeli(x:int) = x+x;
fun doppelr(x:real) = x+x;
33
Primitive Rekursion auf int
Ein Schema oder Schablone:
fun f 0 = ....
| f n = .... f(n-1) ....
Beispiel: 2er Potenzen.
fun power2 0 = 1
| power2 n = 2 * power2 (n-1);
34
Wie viele Teile nach n Schnitten?
35
Wie viele Teile nach n Schnitten?
0 Schnitte: 1 Teil.
Mit dem n-ten Schnitt erhält man n weitere Teile:
fun pieces 0 = 1
| pieces n = pieces(n-1) + n;
36
Nicht alles ist primitiv rekursive
fun ggt 0 n = n
| ggt m n = ggt (n mod m) m;
37
Characters
Letters, digits and special characters.
Literal characters are: #"a" …
Special characters are:
#"\n"
newline
#"\t"
#"\\"
#"\"
tab
backslash
double
quote
38
Characters und strings
"This is a string" : string
Standardfunktionen:
explode: string -> char list
implode: char list -> string
chr :: int -> char
ord :: char -> int
39
Paare und Tupel
(1,2) : int * int
(1,2,true) : int * int * bool
(1,(2,true)) : int * (int * bool)
((1,2),true) : (int * int) * bool
fun
fun
fun
fun
fst(x,y) = x;
snd(x,y) = y;
swap(x,y) = (y,x);
pair x = (x,x);
40
Listen
T list: Listen von Element des Typs T
Leere Liste: []
“Cons”: x :: xs
Endliche Liste:
[1,2,3] = 1::2::3::[]
= 1::(2::(3::[]))
41
Zusammenfassung: Typen
Τ ::= bool | int | ...
|T*T
| T list
| (T,...,T)Typkonstruktor
| T -> T
| (T)
| Typvariable
42
Gleichheit
op = : ’’a
*
’’a
->
bool
’’a ist eine Typvariable über Gleichheitstypen.
Gleichheitstypen sind (in erster Näherung) alle
Typen ohne ->.
1 = 1 : bool
not = not : Typfehler
43
Funktionen
Partielle Anwendung
Sei f: T1 -> T2 -> T und a1:T1.
Dann ist f a1 : T2 -> T eine partielle Anwendung.
Bsp: Gegeben
parser : grammar -> string -> bool
Cgram : grammar
kann man definieren
val Cparser = parser Cgram
> Cparser : string -> bool
45
Currying (nach Haskell B. Curry)
fun f x y = ...
> : T1 -> T2 -> T
fun f(x,y) = ...
> : T1 * T2 -> T
f ist “curried”
f ist “gepaart”
46
Funktionen höherer Stufe =
Funktionen als Parameter
integrate: (real -> real) -> ...
sort: (’a -> ’a -> bool) -> ...
.
.
.
47
Funktionen als Werte
Lambda Kalkül: λx.e
SML: fn x => e : T -> U falls x:T und e:U
x ist formaler Parameter
e ist Funktionskörper, d.h. Resultat
Bsp: fn x => x+1 : int -> int
(fn x => x+1) 41 => 42
48
fun, fn und val
Parameter kann man von links nach rechts
verschieben:
fun f x y = e
ist äquivalent zu
fun f x = fn y => e
fun ist val rec:
fun g x = e
ist äquivalent zu
val rec g = fn x => e
49
Programmierung, Spezifikation und
Verifikation mit Listen
Primitive Rekursion auf list
Ein Schema oder Schablone:
fun f [] = ....
| f (x::xs) = .... f xs ....
Beispiel:
fun length [] = 1
| length (x::xs) = length xs + 1;
51
Wichtige Funktionen auf Listen
fun []
@ ys = ys
| (x::xs) @ ys = x :: (xs @ ys);
fun concat [] = []
| concat(xs::xss) = xs @ concat xss;
Informell:
concat [xs1,...,xsn] = xs1 @ ... @ xsn
fun rev [] = []
| rev (x::xs) = rev xs @ [x];
52
map und filter
fun map f [] = []
| map f (x::xs) = f x :: map f xs
Informell:
map f [x1,...,xn] = [f x1,...,f xn]
fun filter p [] = []
| filter p (x::xs) =
if p x then x :: filter p xs
else filter p xs
53
Taking and ...
fun take n
| take n
if n
else
[] = []
(x:xs) =
<= 0 then []
x :: take (n-1) xs;
fun takeWhile p [] = []
| takeWhile p (x:xs) =
if p x then x :: takeWhile p xs
else [];
54
... dropping
Analog:
drop : int -> ’a list -> ’a list
dropWhile : (’a -> bool) ->
’a list -> ’a list
55
Zipping
fun zipWith f (x::xs) (y::ys) =
f x y :: zipWith f xs ys
| zipWith _ _ _ = [];
Anwendung:
zipWith ??? [x1,...] [y1,...] =
[(x1,y1),...]
zipWith ??? [x1,...] [y1,...] =
[x1+y1,...]
56
Herunterladen