• Keine Ergebnisse gefunden

Praktische Informatik 3: Einführung in die Funktionale Programmierung Vorlesung vom 24.11.2010: Funktionen Höherer Ordnung

N/A
N/A
Protected

Academic year: 2022

Aktie "Praktische Informatik 3: Einführung in die Funktionale Programmierung Vorlesung vom 24.11.2010: Funktionen Höherer Ordnung"

Copied!
37
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

Praktische Informatik 3: Einführung in die Funktionale Programmierung

Vorlesung vom 24.11.2010: Funktionen Höherer Ordnung

Christoph Lüth & Dennis Walter

Universität Bremen

Wintersemester 2010/11

(2)

Fahrplan

I Teil I: Funktionale Programmierung im Kleinen

I Einführung

I Funktionen und Datentypen

I Rekursive Datentypen

I Typvariablen und Polymorphie

I Funktionen höherer Ordnung

I Typinferenz

I Teil II: Funktionale Programmierung im Großen

I Teil III: Funktionale Programmierung im richtigen Leben

(3)

Inhalt

I Funktionenhöherer Ordnung

I Funktionen alsgleichberechtigte Objekte

I Funktionen alsArgumente

I Spezielle Funktionen:map,filter,foldund Freunde

I foldrvs foldl

(4)

Funktionen als Werte

I Argumente können auchFunktionen sein.

I Beispiel: Funktionzweimalanwenden t w i c e :: (α→ α)→ αα t w i c e f x = f ( f x )

I Auswertung wie vorher:

twice inc 3

5

twice (twice inc ) 3 7

I Beispiel: Funktionn-mal hintereinanderanwenden: i t e r :: I n t→ (α→ α)→ αα

i t e r 0 f x = x

i t e r n f x | n > 0 = f ( i t e r ( n−1) f x )

| o t h e r w i s e = x

I Auswertung: iter 3 inc 6

(5)

Funktionen als Werte

I Argumente können auchFunktionen sein.

I Beispiel: Funktionzweimalanwenden t w i c e :: (α→ α)→ αα t w i c e f x = f ( f x )

I Auswertung wie vorher:

twice inc 3 5 twice (twice inc ) 3

7

I Beispiel: Funktionn-mal hintereinanderanwenden: i t e r :: I n t→ (α→ α)→ αα

i t e r 0 f x = x

i t e r n f x | n > 0 = f ( i t e r ( n−1) f x )

| o t h e r w i s e = x

I Auswertung: iter 3 inc 6

(6)

Funktionen als Werte

I Argumente können auchFunktionen sein.

I Beispiel: Funktionzweimalanwenden t w i c e :: (α→ α)→ αα t w i c e f x = f ( f x )

I Auswertung wie vorher:

twice inc 3 5

twice (twice inc ) 3 7

I Beispiel: Funktionn-mal hintereinanderanwenden:

i t e r :: I n t→ (α→ α)→ αα i t e r 0 f x = x

i t e r n f x | n > 0 = f ( i t e r ( n−1) f x )

| o t h e r w i s e = x

I Auswertung:

iter 3 inc

6

(7)

Funktionen als Werte

I Argumente können auchFunktionen sein.

I Beispiel: Funktionzweimalanwenden t w i c e :: (α→ α)→ αα t w i c e f x = f ( f x )

I Auswertung wie vorher:

twice inc 3 5

twice (twice inc ) 3 7

I Beispiel: Funktionn-mal hintereinanderanwenden:

i t e r :: I n t→ (α→ α)→ αα i t e r 0 f x = x

i t e r n f x | n > 0 = f ( i t e r ( n−1) f x )

| o t h e r w i s e = x

I Auswertung:

(8)

Funktionen Höherer Ordnung

Slogan

“Functions are first-class citizens.”

I Funktionen sindgleichberechtigt: Werte wiealle anderen

I Grundprinzipder funktionalen Programmierung

I Reflektion

I FunktionenalsArgumente

(9)

Funktionen als Argumente: Funktionskomposition

I Funktionskomposition(mathematisch) (◦) :: (βγ) → (αβ)→ αγ

( f ◦ g ) x = f ( g x )

I Vordefiniert

I Lies:f nachg

I Funktionskompositionvorwärts:

(>.>) :: (α→ β)→ (βγ)→ αγ ( f >.> g ) x = g ( f x )

I Nichtvordefiniert!

(10)

Funktionen als Argumente: Funktionskomposition

I Vertauschen derArgumente (vordefiniert):

f l i p :: (α→ βγ)→ βαγ f l i p f b a = f a b

I Damit Funktionskomposition vorwärts:

(>.>) :: (α→ β)→ (βγ)→ αγ (>.>) f g x = f l i p (◦) f g x

I Operatorennotation

(11)

η-Kontraktion

I Alternative Definition der Vorwärtskomposition:PunktfreieNotation (>.>) :: (α→ β)→ (βγ)→ αγ

(>.>) = f l i p (◦)

I Da fehlt doch was?!

Nein:

(>.>) =flip (◦) ≡ (>.>) f g a =flip (◦) f g a

I η-Kontraktion (η-Äquivalenz)

I Bedingung:E :: α→β, x :: α,Edarfxnicht enthalten λx→E x E

I Syntaktischer SpezialfallFunktionsdefinition: f x =E x f =E

I Warum?ExtensionaleGleichheit von Funktionen

(12)

η-Kontraktion

I Alternative Definition der Vorwärtskomposition:PunktfreieNotation (>.>) :: (α→ β)→ (βγ)→ αγ

(>.>) = f l i p (◦)

I Da fehlt doch was?! Nein:

(>.>) =flip (◦) ≡ (>.>) f g a =flip (◦) f g a

I η-Kontraktion (η-Äquivalenz)

I Bedingung:E :: α→β,x :: α,Edarfxnicht enthalten λx→E x E

I Syntaktischer SpezialfallFunktionsdefinition:

f x =E x f =E

I Warum?ExtensionaleGleichheit von Funktionen

(13)

Funktionen als Argumente: map

I Funktionauf alle Elemente anwenden:map

I Signatur:

map :: (αβ)→ [α]→ [β]

I Definition

map f [ ] = [ ]

map f ( x : x s ) = f x : map f x s

I Beispiel:

t o L :: S t r i n g→ S t r i n g t o L = map t o L o w e r

(14)

Funktionen als Argumente: filter

I Elementefiltern:filter

I Signatur:

f i l t e r :: (α→ B o o l )→ [α]→ [α]

I Definition

f i l t e r p [ ] = [ ] f i l t e r p ( x : x s )

| p x = x : f i l t e r p x s

| o t h e r w i s e = f i l t e r p x s

I Beispiel:

l e t t e r s :: S t r i n g→ S t r i n g l e t t e r s = f i l t e r i s A l p h a

(15)

Beispiel: Primzahlen

I Sieb des Erathostenes

I Für jedegefundene PrimzahlpalleVielfachenheraussieben

I Dazu:filtern mit\n→mod n p/=0!

I Namenlose(anonyme) Funktion

I Primzahlen im Intervall[1.. n]:

s i e v e :: [ I n t e g e r ]→ [ I n t e g e r ] s i e v e [ ] = [ ]

s i e v e ( p : p s ) =

p : s i e v e ( f i l t e r ( \n→ mod n p /= 0 ) p s ) p r i m e s :: I n t e g e r→ [ I n t e g e r ]

p r i m e s n = s i e v e [ 2 . . n ]

I NB: Mit2 anfangen!

I Listengenerator[n.. m]

(16)

Partielle Applikation

I Funktionskonstruktorrechtsassoziativ:

a → b→c≡a→ (b→c)

I Inbesondere: (a b)→ c6=a→ (b→c)

I Funktionsanwendung istlinksassoziativ:

f a b≡( f a) b

I Inbesondere: f (a b)6=( f a) b

I PartielleAnwendung von Funktionen:

I Für f :: a→b→c,x :: aist f x :: b→c(closure)

I Beispiele:

I map toLower:: String→ String

I (3 ==):: Int→Bool

I concatmap ( replicate 2) :: String→ String

(17)

Partielle Applikation

I Funktionskonstruktorrechtsassoziativ:

a → b→c≡a→ (b→c)

I Inbesondere: (a b)→ c6=a→ (b→c)

I Funktionsanwendung istlinksassoziativ:

f a b≡( f a) b

I Inbesondere: f (a b)6=( f a) b

I PartielleAnwendung von Funktionen:

I Für f :: a→b→c,x :: aist f x :: b→c(closure)

I Beispiele:

I map toLower:: String→ String

I (3 ==):: IntBool

I concatmap ( replicate 2) :: String→ String

(18)

Einfache Rekursion

I Einfache Rekursion: gegeben durch

I eine Gleichungfür die leere Liste

I eine Gleichungfür die nicht-leere Liste

I Beispiel:sum,concat,length, (++), . . .

I Auswertung:

sum [4,7,3]

4 + 7 + 3 + 0

concat [A, B, C] A ++ B ++ C++ []

length [4, 5, 6] 1+ 1+ 1+ 0

(19)

Einfache Rekursion

I Einfache Rekursion: gegeben durch

I eine Gleichungfür die leere Liste

I eine Gleichungfür die nicht-leere Liste

I Beispiel:sum,concat,length, (++), . . .

I Auswertung:

sum [4,7,3] 4 + 7 + 3 + 0

concat [A, B, C]

A ++ B ++ C++ [] length [4, 5, 6] 1+ 1+ 1+ 0

(20)

Einfache Rekursion

I Einfache Rekursion: gegeben durch

I eine Gleichungfür die leere Liste

I eine Gleichungfür die nicht-leere Liste

I Beispiel:sum,concat,length, (++), . . .

I Auswertung:

sum [4,7,3] 4 + 7 + 3 + 0

concat [A, B, C] A ++ B ++ C++ []

length [4, 5, 6]

1+ 1+ 1+ 0

(21)

Einfache Rekursion

I Einfache Rekursion: gegeben durch

I eine Gleichungfür die leere Liste

I eine Gleichungfür die nicht-leere Liste

I Beispiel:sum,concat,length, (++), . . .

I Auswertung:

sum [4,7,3] 4 + 7 + 3 + 0

concat [A, B, C] A ++ B ++ C++ []

length [4, 5, 6] 1+ 1+ 1+ 0

(22)

Einfache Rekursion

I Allgemeines Muster:

f [] = A

f (x:xs) = x⊗f xs

I Parameterder Definition:

I Startwert (für die leere Liste)A :: b

I Rekursionsfunktion:: a -> b-> b

I Auswertung:

f [x1,..., xn]=x1⊗x2⊗. . .⊗xn⊗A

I Terminiertimmer

I Entspricht einfacherIteration(while-Schleife)

(23)

Einfach Rekursion durch foldr

I EinfacheRekursion

I Basisfall: leere Liste

I Rekursionsfall: Kombination aus Listenkopf und Rekursionswert

I Signatur

f o l d r :: (α→ ββ)→ β→ [α]→ β

I Definition

f o l d r f e [ ] = e

f o l d r f e ( x : x s ) = f x ( f o l d r f e x s )

(24)

Beispiele: foldr

I Summierenvon Listenelementen.

sum :: [ I n t ]→ I n t sum x s = f o l d r (+) 0 x s

I Flachklopfenvon Listen.

c o n c a t :: [ [ a ] ]→ [ a ]

c o n c a t x s = f o l d r (++) [ ] x s

I Längeeiner Liste

l e n g t h :: [ a ]→ I n t

l e n g t h x s = f o l d r (λx n→ n+ 1 ) 0 x s

(25)

Noch ein Beispiel: rev

I Listenumdrehen:

r e v :: [ a ]→ [ a ] r e v [ ] = [ ]

r e v ( x : x s ) = r e v x s ++ [ x ]

I Mitfold:

r e v x s = f o l d r s n o c [ ] x s s n o c :: a→ [ a ]→ [ a ] s n o c x x s = x s ++ [ x ]

I Unbefriedigend: doppelte Rekursion

(26)

Einfache Rekursion durch foldl

I foldrfaltet vonrechts:

foldr⊗[x1, ...,xn]A=x1⊗(x2⊗(. . .(xn⊗A)))

I Warum nichtandersherum?

foldl⊗[x1, ...,xn]A= (((A⊗x1)⊗x2). . .)⊗xn

I Definition vonfoldl:

f o l d l :: (α → βα)α → [β] → α

f o l d l f a [ ] = a

f o l d l f a ( x : x s ) = f o l d l f ( f a x ) x s

(27)

Beispiel: rev revisited

I Listenumkehr ist faltenvon links:

r e v ’ x s = f o l d l ( f l i p ( : ) ) [ ] x s

I Nur nocheineRekursion

(28)

foldr vs. foldl

I f=foldr⊗A entspricht

f [] = A

f (x:xs) = x⊗f xs

I Kann nicht-strikt inxssein, z.B.and,or

I f=foldl⊗Aentspricht

f xs = g A xs

g a [] = a

g a (x:xs) = g(a⊗x) xs

I Endrekursiv(effizient), aber strikt inxs

(29)

foldl = foldr

Definition (Monoid)

(⊗,A)ist ein Monoidwenn

A⊗x=x (Neutrales Element links) x⊗A=x (Neutrales Element rechts) (x⊗y)⊗z=x⊗(y⊗z) (Assoziativät)

Theorem

Wenn (⊗,A) Monoid, dann für alle A,xs

foldlA xs=foldrA xs

I Beispiele:length,concat,sum

I Gegenbeispiel:rev

(30)

Funktionen Höherer Ordnung: Java

I Java: keine direkte Syntax für Funktionen höherer Ordnung

I Folgendes istnicht möglich:

i n t e r f a c e C o l l e c t i o n {

O b j e c t f o l d ( O b j e c t f ( O b j e c t a , C o l l e c t i o n c ) , O b j e c t a ) }

I Aber folgendes:

i n t e r f a c e F o l d a b l e { O b j e c t f ( O b j e c t a ) ; } i n t e r f a c e C o l l e c t i o n {

O b j e c t f o l d ( F o l d a b l e f , O b j e c t a ) ; }

I VergleicheIterator aus Collections Framework (Java SE 6):

p u b l i c i n t e r f a c e I t e r a t o r<E>

b o o l e a n h a s N e x t ( ) ; E n e x t ( ) ; }

(31)

Funktionen Höherer Ordnung: C

I Implizitvorhanden: Funktionen = Zeiger auf Funktionen t y p e d e f s t r u c t l i s t _ t {

v o i d ∗e l e m ;

s t r u c t l i s t _ t ∗n e x t ; } ∗l i s t ;

l i s t f i l t e r (i n t f (v o i d ∗x ) , l i s t l ) ;

I Keinedirekte Syntax (e.g. namenlose Funktionen)

I Typsystem zuschwach (keine Polymorphie)

I Benutzung:signal(C-Standard 7.14.1)

#i n c l u d e <s i g n a l . h>

v o i d (∗s i g n a l (i n t s i g , v o i d (∗f u n c ) (i n t) ) ) (i n t) ;

(32)

Funktionen Höherer Ordnung: C

Implementierung von filter:

l i s t f i l t e r (i n t f (v o i d ∗x ) , l i s t l ) { i f ( l == NULL ) {

r e t u r n NULL ; }

e l s e { l i s t r ;

r= f i l t e r ( f , l→ n e x t ) ; i f ( f ( l→ e l e m ) ) {

l→n e x t= r ; r e t u r n l ; }

e l s e { f r e e ( l ) ; r e t u r n r ;

} } }

(33)

Übersicht: vordefinierte Funktionen auf Listen II

map :: (αβ)→ [α]→ [β] −−Auf alle anwenden f i l t e r :: (α→ B o o l )→ [α]→ [α] −−Elemente filtern f o l d r :: (αββ)→ β→ [α]→ β −−Falten v. rechts f o l d l :: (βαβ)→ β→ [α]→ β −−Falten v. links t a k e W h i l e :: (α→ B o o l )→ [α]→ [α]

d r o p W h i l e :: (α→ B o o l )→ [α]→ [α]

−−takeWhile ist längster Prefix so dass p gilt, dropWhile der Rest any :: (α → B o o l ) → [α] → B o o l −−p gilt mind. einmal

a l l :: (α → B o o l ) → [α] → B o o l −−p gilt für alle e l e m :: ( Eq α) ⇒ α → [α] → B o o l −−Ist enthalten?

z i p W i t h :: (αβγ) → [α] → [β] → [γ]

−−verallgemeinertes zip

(34)

Allgemeine Rekursion

I EinfacheRekursion ist Spezialfallder allgemeinen Rekursion

I AllgemeineRekursion:

I Rekursion übermehrere Argumente

I Rekursion überandere Datenstruktur

I Andere Zerlegungals Kopf und Rest

(35)

Beispiele für allgemeine Rekursion: Sortieren

I Quicksort:

I zerlege Liste in Elementekleiner,gleichundgrößerdem ersten,

I sortiereTeilstücke,konkateniereErgebnisse

I Mergesort:

I teileListe in derHälfte,

I sortiereTeilstücke, fügeordnungserhaltendzusammen.

(36)

Beispiel für allgemeine Rekursion: Mergesort

I Hauptfunktion:

m s o r t :: Ord α⇒ [α]→ [α] m s o r t x s

| l e n g t h x s ≤ 1 = x s

| o t h e r w i s e = merge ( m s o r t f ) ( m s o r t b ) where ( f , b ) = s p l i t A t ( ( l e n g t h x s ) ‘ d i v ‘ 2 ) x s

I splitAt :: Int [α]→ ([α], [α]) spaltetListe auf

I Hilfsfunktion: ordnungserhaltendes Zusammenfügen merge :: Ord α⇒ [α]→ [α]→ [α] merge [ ] x = x

merge y [ ] = y merge ( x : x s ) ( y : y s )

| x≤ y = x : ( merge x s ( y : y s ) )

| o t h e r w i s e = y : ( merge ( x : x s ) y s )

(37)

Zusammenfassung

I Funktionenhöherer Ordnung

I Funktionen alsgleichberechtigte ObjekteundArgumente

I Partielle Applikation,η-Kontraktion, namenlose Funktionen

I Spezielle Funktionen höherer Ordnung:map, filter, foldund Freunde

I Formen derRekursion:

I EinfacheundallgemeineRekursion

I EinfacheRekursion entsprichtfoldr

Referenzen

ÄHNLICHE DOKUMENTE

Praktische Informatik 3: Funktionale Programmierung Vorlesung 5 vom 15.11.2016: Funktionen Höherer Ordnung I..

I Eine Funktion hat ein Speicherleck, wenn Speicher unnötig lange im Zugriff bleibt. I “Echte” Speicherlecks wie in C/C++

I Striktheit: Speicherlecks vermeiden (bei verzögerter Auswertung) I Vorteil: Effizienz muss nicht im Vordergrund stehen. PI3 WS 16/17

Praktische Informatik 3: Funktionale Programmierung Vorlesung 5 vom 11.11.2014: Funktionen Höherer Ordnung I..

Praktische Informatik 3: Funktionale Programmierung Vorlesung 5 vom 11.11.2014: Funktionen Höherer Ordnung I.. Christoph Lüth Universität Bremen

Praktische Informatik 3: Funktionale Programmierung Vorlesung 6 vom 18.11.2014: Funktionen Höherer Ordnung II..

Praktische Informatik 3: Funktionale Programmierung Vorlesung 6 vom 18.11.2014: Funktionen Höherer Ordnung II.. Christoph Lüth Universität Bremen

Praktische Informatik 3: Funktionale Programmierung Vorlesung 5 vom 11.11.2014: Funktionen Höherer Ordnung I.