Einführung in die funktionale Programmierung€¦ · 1 Einführung in die funktionale...

40
1

Transcript of Einführung in die funktionale Programmierung€¦ · 1 Einführung in die funktionale...

Page 1: Einführung in die funktionale Programmierung€¦ · 1 Einführung in die funktionale Programmierung Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie

1

Einführung in die funktionaleProgrammierung

Prof. Dr. Manfred Schmidt-Schauÿ

Künstliche Intelligenz und Softwaretechnologie

27. Oktober 2009

Page 2: Einführung in die funktionale Programmierung€¦ · 1 Einführung in die funktionale Programmierung Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie

Haskell - Einfuhrung

Einfuhrung in die funktionale Programmierung, fol2-2 - 1 -

• Syntax

• Typen

• Auswertung

• Programmierung

Als erweiterte Kernsprache: KFPTSPmit polymorpher Typisierung(wird noch spezifiziert)

Page 3: Einführung in die funktionale Programmierung€¦ · 1 Einführung in die funktionale Programmierung Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie

Polymorphe Typen

Einfuhrung in die funktionale Programmierung, fol2-2 - 2 -

Syntax:

T ::= V | (TC T1 . . . Tn) | (T1 → T2)

wobei V Typvariable,Ti TypenTC (parametrisierter) Typkonstruktor

Beispiele: zu Typkonstruktoren:

Bool

List a bzw. [a].

Parameter a: Typ der Elemente der Liste.

Page 4: Einführung in die funktionale Programmierung€¦ · 1 Einführung in die funktionale Programmierung Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie

Typkonstruktoren: Beispiele

Einfuhrung in die funktionale Programmierung, fol2-2 - 3 -

data [a] = [] | (a : [a])

data Vector a = Vectordaten [a]

Page 5: Einführung in die funktionale Programmierung€¦ · 1 Einführung in die funktionale Programmierung Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie

Typen: Beispiele

Einfuhrung in die funktionale Programmierung, fol2-2 - 4 -

True :: BoolFalse :: Bool&& :: Bool → Bool → Bool|| :: Bool → Bool → Bool

Cons :: a → [a] → [a] a ist TypvariableNil :: [a] a ist Typvariable(:) :: a → [a] → [a] a ist Typvariable[] :: [a] a ist Typvariable

Page 6: Einführung in die funktionale Programmierung€¦ · 1 Einführung in die funktionale Programmierung Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie

Typen: (vereinfachte) Typregeln

Einfuhrung in die funktionale Programmierung, fol2-2 - 5 -

•f :: a → b; s :: a

(f s) :: b

•s :: T

s :: T ′ wobei T ′ = σ(T ) und σ eine Einset-

zung von Typen fur Typvariablen ist.

•s :: T ; t1 : a, . . . , tn :: a

(caseT s of {pat1-> t1; . . .}) :: a(fur nullstellige Typkonstruktoren)

Es fehlen: pattern, guards, list comprehensions, ...

Page 7: Einführung in die funktionale Programmierung€¦ · 1 Einführung in die funktionale Programmierung Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie

Typen: Beispiele

Einfuhrung in die funktionale Programmierung, fol2-2 - 6 -

Typ des Ausdrucks True && False unter Verwendung der Regeln:

&& :: Bool → Bool → Bool; True : Bool

(&& True) :: Bool → Bool; False : Bool

(&& True False) :: Bool

Page 8: Einführung in die funktionale Programmierung€¦ · 1 Einführung in die funktionale Programmierung Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie

Typen: Beispiele

Einfuhrung in die funktionale Programmierung, fol2-2 - 7 -

(:) :: α → [α] → [α], 1 : Int

(1 :) :: [Int] → [Int]; [] :: [α′]

(1 : []) ::: [Int]

Typvariablen sind zu instanziieren!

Typisierung benutzt auch speziellere Typen,

nicht nur die allgemeinsten

Page 9: Einführung in die funktionale Programmierung€¦ · 1 Einführung in die funktionale Programmierung Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie

Typen: Beispiele

Einfuhrung in die funktionale Programmierung, fol2-2 - 8 -

Muss man manchmal beide Typen

f : τ1 → τ2 und s :: τ3 instanziieren,

so dass die Regel anwendbar wird?

f :: τ1 → τ2; s :: τ3(f s) :: τ4

Page 10: Einführung in die funktionale Programmierung€¦ · 1 Einführung in die funktionale Programmierung Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie

Typen: Beispiele

Einfuhrung in die funktionale Programmierung, fol2-2 - 9 -

concatMap :: (a → [b]) → [a] → [b]

reverse :. [c] → [c]

(concatMap reverse) :: [[a]] → [a]

Page 11: Einführung in die funktionale Programmierung€¦ · 1 Einführung in die funktionale Programmierung Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie

Arithmetische Operatoren in Haskell

Einfuhrung in die funktionale Programmierung, fol2-2 - 10 -

Besonderheiten der Typisierung in Haskell.

• beschrankte ganze Zahlen (Int),• unbeschrankte ganze Zahlen (Integer),• Gleitkommazahlen (Float),• doppelt genaue Gleitkommazahlen (Double),• rationale Zahlen (Ratio α).

2 ∗ 2 = 42.0/3.0 = 0.666666667(1%2)/(3%2) = (1%3) :: Ratio Integer(123456789 :: Int)∗

(987654321 :: Int) = −67153019 :: Int123456789 ∗ 987654321 = 121932631112635269 :: Integer

Page 12: Einführung in die funktionale Programmierung€¦ · 1 Einführung in die funktionale Programmierung Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie

Arithmetische Operatoren in Haskell

Einfuhrung in die funktionale Programmierung, fol2-2 - 11 -

Typklasse Num der numerischen Typen

+,−, ∗ auf allen Objekten mit Typ aus der Typklasse Num

(+): Num a => a -> a -> a

Fractional: Typen, fur die “/” erlaubt (z.B. nicht fur Int )

Page 13: Einführung in die funktionale Programmierung€¦ · 1 Einführung in die funktionale Programmierung Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie

Zahlen und Arithmetische Funktionen: Imple-mentierung in KFPTSP

Einfuhrung in die funktionale Programmierung, fol2-2 - 12 -

Implementierung von Integer in KFPTSP

Peanozahlen: Typ Pint aufgebaut mit zwei Konstruktoren:

S einstellig0 nullstellig

0, (S 0), S(S 0), S(S(S 0)), . . .

implementieren die nicht-negativen ganzen Zahlen 0,1,2,3, . . ..

Page 14: Einführung in die funktionale Programmierung€¦ · 1 Einführung in die funktionale Programmierung Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie

Arithmetische Funktionen

Einfuhrung in die funktionale Programmierung, fol2-2 - 13 -

(Haskell-Variante der KFPTSP Definitionen)

data Pint = Zero | Succ Pint

deriving (Eq, Show)

istZahl x = case x of {Zero -> True; Succ y -> istZahl y}

peanoPlus x y = if istZahl x && istZahl y

then pplus x y else bot

pplus x y = case x of Zero -> y

Succ z -> Succ (pplus z y)

Der Haskell-Typ der Funktionen ist:

• istZahl :: Pint → Bool• peanoPlus :: Pint → Pint → Pint• pplus :: Pint → Pint → Pint

Page 15: Einführung in die funktionale Programmierung€¦ · 1 Einführung in die funktionale Programmierung Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie

Arithmetische Funktionen

Einfuhrung in die funktionale Programmierung, fol2-2 - 14 -

istZahl bewirkt das korrekte Terminierungsverhalten

Z.B. (+ bot 1) als auch (+ 1 bot) terminieren nicht.

D.h. auch (peanoPlus bot (Succ Zero)) und

(peanoPlus (Succ Zero) bot)

durfen nicht terminieren.

Beachte: (pplus (Succ Zero) bot) terminiert

Page 16: Einführung in die funktionale Programmierung€¦ · 1 Einführung in die funktionale Programmierung Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie

Arithmetische Pradikate

Einfuhrung in die funktionale Programmierung, fol2-2 - 15 -

fur nichtnegative ganze Zahlen:

peanoleq x y =

(istZahl x) &&

(istZahl y) &&

(case x of

{Zero -> True;

Succ xx ->

case y of

{Zero -> False;

Succ yy -> peanoleq xx yy}})

Page 17: Einführung in die funktionale Programmierung€¦ · 1 Einführung in die funktionale Programmierung Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie

Arithmetische Funktionen: Beispiel

Einfuhrung in die funktionale Programmierung, fol2-2 - 16 -

Die Fakultatsfunktion auf Peanozahlen:

pmal x y = case x of Zero -> Zero

Succ z -> pplus (pmal z y) y

pfak x = case x of Zero -> Succ Zero

Succ z -> (pmal x (pfak z))

Page 18: Einführung in die funktionale Programmierung€¦ · 1 Einführung in die funktionale Programmierung Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie

Arithmetische Funktionen

Einfuhrung in die funktionale Programmierung, fol2-2 - 17 -

Wir konnen annehmen, dass alle arithmetischen Funktionen

in KFPTSP definiert sind.

Problematisch ware: Zahlen als Konstantenarithmetische Funktionen als

Funktion auf unendlich vielen Konstanten

Page 19: Einführung in die funktionale Programmierung€¦ · 1 Einführung in die funktionale Programmierung Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie

Tupel, Paare in Haskell

Einfuhrung in die funktionale Programmierung, fol2-2 - 18 -

Beispiel

5- Tupel: (1,2,3,4,5).

Ubersetzung nach KFPT (bzw, KFPSP)

als Typ mit 5-stelligem Konstruktor Tupel5

Tupel5 :: a1 → a2 → a3 → a4 → a5 → (a1, a2, a3, a4, a5)

Es gibt ein null-stelliges Tupel, geschrieben ().

kein einstelliges Tupel.

Page 20: Einführung in die funktionale Programmierung€¦ · 1 Einführung in die funktionale Programmierung Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie

Tupel, Paare ; Selektoren

Einfuhrung in die funktionale Programmierung, fol2-2 - 19 -

Selektoren liefern die einzelnen Komponenten eines Tupels

In Haskell mit Pattern realisiert:

fst x = case x of {(u, v) -> u}

snd x = case x of {(u, v) -> v}

oder einfacher in Haskell, aber aquivalent:

fst (u, v) = u

snd (u, v) = v

Page 21: Einführung in die funktionale Programmierung€¦ · 1 Einführung in die funktionale Programmierung Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie

Tupel, Paare ; Selektoren

Einfuhrung in die funktionale Programmierung, fol2-2 - 20 -

Kodierung in KFPTSP erfordert die Angabe des Typs:

fst x = case_Tupel2 x of {Tupel2 u v -> u}

snd x = case_Tupel2 x of {Tupel2 u v -> v}

Page 22: Einführung in die funktionale Programmierung€¦ · 1 Einführung in die funktionale Programmierung Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie

Haskell-Listen-Funktionen

Einfuhrung in die funktionale Programmierung, fol2-2 - 21 -

Beispiel-Definitionen und Verwendung

letztes_element [] = error "Liste leer"

letztes_element (x:xs) = if (case xs of [] -> False; (y:ys) -> True)

then x

else letztes_element xs

Zur Info: diese Funktion ist end-rekursiv

Page 23: Einführung in die funktionale Programmierung€¦ · 1 Einführung in die funktionale Programmierung Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie

Listen von Zahlen

Einfuhrung in die funktionale Programmierung, fol2-2 - 22 -

[1..10] ----> [1,2,3,4,5,6,7,8,9,10]

[1..] ----> [1,2,3,4,5,6,7,8,9,10,11,.....

interne Definitionen: (Nach KFPTSP ubersetzbar)

upto m n = if m > n then []

else m : (upto (m+1) n)

from m = m : (from (m+1))

Page 24: Einführung in die funktionale Programmierung€¦ · 1 Einführung in die funktionale Programmierung Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie

map, append, filter, reverse, fold, ...

Einfuhrung in die funktionale Programmierung, fol2-2 - 23 -

map f xs = case xs of {Nil -> Nil; Cons h t -> Cons (f h) (map f t)}

Haskell-Definition:

map :: (a -> b) -> [a] -> [b]

map f [] = []

map f (x:xs) = (f x) : (map f xs)

Page 25: Einführung in die funktionale Programmierung€¦ · 1 Einführung in die funktionale Programmierung Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie

map, append, filter, reverse, ...

Einfuhrung in die funktionale Programmierung, fol2-2 - 24 -

Die Funktion append, Infix geschrieben als ++:

++ xs ys = case xs of {Nil -> ys; Cons h t -> Cons h (t ++ ys )}

Die Haskell-Definition ist:

(++) :: [a] -> [a] -> [a]

[] ++ ys = ys

(x:xs) ++ ys = x:(xs ++ ys)

Page 26: Einführung in die funktionale Programmierung€¦ · 1 Einführung in die funktionale Programmierung Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie

map, append, filter, reverse, fold, ...

Einfuhrung in die funktionale Programmierung, fol2-2 - 25 -

Lange einer Liste:

length xs = case xs of {Nil -> 0; Cons h t -> (1 + (length t))}

Die Haskell-Definition ist:

length :: [a] -> Int

length [] = 0

length (_:t) = 1 + (length t)

Page 27: Einführung in die funktionale Programmierung€¦ · 1 Einführung in die funktionale Programmierung Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie

map, append, filter, reverse, fold, ...

Einfuhrung in die funktionale Programmierung, fol2-2 - 26 -

zip :: [a] -> [b] -> [(a,b)]

zip [] [] = []

zip [] xs = []

zip xs [] = []

zip (x:xs) (y:ys) = (x,y) : (zip xs ys)

unzip :: [(a,b)] -> ([a],[b])

unzip [] = ([],[])

unzip ((x,y):xs) = (x:xl, y:yl)

where (xl,yl) = unzip xs

Page 28: Einführung in die funktionale Programmierung€¦ · 1 Einführung in die funktionale Programmierung Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie

concatMap:

Einfuhrung in die funktionale Programmierung, fol2-2 - 27 -

concatMap :: (a -> [b]) -> [a] -> [b]

concatMap f [] = []

concatMap f (x:xs) = (f x) ++ concatMap f xs

concatMap f xs entspricht concat (map f xs)

Page 29: Einführung in die funktionale Programmierung€¦ · 1 Einführung in die funktionale Programmierung Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie

map, append, filter, reverse, fold, ...

Einfuhrung in die funktionale Programmierung, fol2-2 - 28 -

reverse :: [a] -> [a]

reverse xs = case xs of {Nil -> Nil; Cons h t -> ((reverse t) ++ [h])}

Z.B. reverse [1,2,3] → [3,2,1]

Eine mogliche Haskell-Definition ist:

reverse [] = []

reverse (h:t) = (reverse t) ++ [h]

Laufzeit: O(n2).

Page 30: Einführung in die funktionale Programmierung€¦ · 1 Einführung in die funktionale Programmierung Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie

map, append, filter, reverse, fold, ...

Einfuhrung in die funktionale Programmierung, fol2-2 - 29 -

Die effizientere Methode ist die Verwendung eines Stacks:

reverse x = rev_accu x []

rev_accu xs stack = case xs of {[] -> stack;

h:t -> (rev_accu t (h:stack))}

rev accu ist endrekursiv (tail-recursive)

vordefiniert in Haskell:

flip f x y = f y x

reverse :: [a] -> [a]

reverse = foldl (flip (:)) []

Page 31: Einführung in die funktionale Programmierung€¦ · 1 Einführung in die funktionale Programmierung Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie

map, append, filter, reverse, fold, ...

Einfuhrung in die funktionale Programmierung, fol2-2 - 30 -

Transpose: einer Matrix als Liste von Listen.

(1 23 4

)wird als [[1,2], [3,4]] dargestellt.

hd xs = case xs of {h:t -> h; [] -> bot}

tl xs = case xs of {h:t -> t; [] -> bot}

transpose xss = case xss of

{[] -> bot;

h:t ->

case h of {[] -> [];

h:t -> (map hd xss)

: (transpose (map tl xss))}}

Page 32: Einführung in die funktionale Programmierung€¦ · 1 Einführung in die funktionale Programmierung Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie

map, append, filter, reverse, fold, ...

Einfuhrung in die funktionale Programmierung, fol2-2 - 31 -

Haskell-Definition von transpose

transpose ([] : rest) = []

transpose x = (map hd x) : (transpose (map tl x))

Die Typen sind:

hd :: [a] → a

tl :: [a] → [a]

transpose :: [[a]] → [[a]]

Page 33: Einführung in die funktionale Programmierung€¦ · 1 Einführung in die funktionale Programmierung Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie

map, append, filter, reverse, fold, ...

Einfuhrung in die funktionale Programmierung, fol2-2 - 32 -

transpose [[1,2], [3,4], [5,6]] ergibt bei der Auswertung nacheinander:

[1,3,5] : transpose [[2], [4], [6]]→ [[1,3,5], [2,4,6]]

Beachte: es gibt in Haskell den Datentyp Array (siehe Handbuch)

Page 34: Einführung in die funktionale Programmierung€¦ · 1 Einführung in die funktionale Programmierung Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie

Listenfunktionen Beispiele

Einfuhrung in die funktionale Programmierung, fol2-2 - 33 -

vectoradd_1 xs ys = map vadd (transpose [xs, ys])

vadd [x,y] = x + y

optimierte Version:

zipWith :: ( a-> b-> c) -> [a] -> [b] -> [c]

vectoradd_2 = zipWith (+)

Page 35: Einführung in die funktionale Programmierung€¦ · 1 Einführung in die funktionale Programmierung Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie

Let und Where

Einfuhrung in die funktionale Programmierung, fol2-2 - 34 -

let, where sind rekursive Bindungsoperatoren

let x1 = t1; . . . ;xn = tn in Exp

entspricht

Exp where x1 = t1; . . . ;xn = tn

Beachte, dass im Haskell-Report die Verwendung des where eingeschrankt ist.

Ein nicht-rekursives let (where) ist einfach darstellbar:

let x_1 = t_1;.... ; x_n = t_n in Exp

entspricht dann (in etwa)

(\x_1 .... x_n -> Exp) t_1 ... t_n

Page 36: Einführung in die funktionale Programmierung€¦ · 1 Einführung in die funktionale Programmierung Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie

Rekursives Let: Beispiel

Einfuhrung in die funktionale Programmierung, fol2-2 - 35 -

Unendliche Liste mit gleichen Elementen:

let x = 10 : x in x

[10,10,10, ...

rekursive Definition von length:

let length = (\xs -> case xs of {[] -> 0; (y:ys) -> 1+(length ys)})

in (length [1..10])

Page 37: Einführung in die funktionale Programmierung€¦ · 1 Einführung in die funktionale Programmierung Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie

Filter

Einfuhrung in die funktionale Programmierung, fol2-2 - 36 -

filter :: (a -> Bool) -> [a] -> [a]

filter pred [] = []

filter pred (h:t) = if pred h then h:rest

else rest

where rest = filter pred t

remove p xs = filter (\x -> not (p(x))) xs

Oder kurzer geschrieben:

remove p = filter ( not . p)

Page 38: Einführung in die funktionale Programmierung€¦ · 1 Einführung in die funktionale Programmierung Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie

Komposition von einstelligen Funktionen

Einfuhrung in die funktionale Programmierung, fol2-2 - 37 -

Geschrieben als Punkt: .

(.) :: (b -> c) -> (a -> b) -> a -> c

f . g = \x -> f (g x)

Page 39: Einführung in die funktionale Programmierung€¦ · 1 Einführung in die funktionale Programmierung Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie

Maybe, Just und Nothing

Einfuhrung in die funktionale Programmierung, fol2-2 - 38 -

data Maybe a = Nothing | Just a

Vordefinierter Typ.

Zweck: Markieren und Weitergeben von Daten

Nothing Kein Wert gefundenJust s s wurde gefunden und wird weitergegeben

Page 40: Einführung in die funktionale Programmierung€¦ · 1 Einführung in die funktionale Programmierung Prof. Dr. Manfred Schmidt-Schauÿ Künstliche Intelligenz und Softwaretechnologie

Maybe-Beispiel

Einfuhrung in die funktionale Programmierung, fol2-2 - 39 -

Beispiel Suche in einer Assoziationsliste-Liste:al = [(”gruen”,1), (”blau”,2), (”rot”,3)]

sucheAL key [] = Nothing

sucheAL key ((k,v):rest) = if key == k then Just v

else sucheAL key rest

*Main> sucheAL "rot" al

Just 3

*Main> sucheAL "braun" al

Nothing

Verwendung:

case (sucheAL farbe al) of

Nothing -> ...

Just a -> ... a ...