• Keine Ergebnisse gefunden

Funktionen höherer Ordnung

N/A
N/A
Protected

Academic year: 2022

Aktie "Funktionen höherer Ordnung"

Copied!
5
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

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

Christoph Lüth Universität Bremen Wintersemester 2012/13

Rev. 1874 1 [33]

Fahrplan

I Teil I: Funktionale Programmierung im Kleinen

IEinführung

IFunktionen und Datentypen

IRekursive Datentypen

ITypvariablen und Polymorphie

IFunktionen höherer Ordnung I

IFunktionen höherer Ordnung II

ITypinferenz

I Teil II: Funktionale Programmierung im Großen I Teil III: Funktionale Programmierung im richtigen Leben

2 [33]

Funktionen höherer Ordnung

I mapundfiltersind durchfoldrdarstellbar:

map :: (α→ β)→ [α]→ [β] map f = f o l d r (λa b→ f a : b ) [ ]

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

f i l t e r p= f o l d r (λa a si f p a then a : a s e l s e a s ) [ ]

foldrist diekanonische einfach rekursiveFunktion.

I Alle einfach rekursiven Funktionen sind als Instanz vonfoldr darstellbar.

foldr (:) [ ]=id

3 [33]

map als strukturerhalten Abbildung

mapist die kanonischestrukturerhaltende Abbildung.

I Struktur(Shape) eines DatentypsTαistT().

IFür Listen: [()]∼=Nat.

I Fürmapgelten folgende Aussagen:

map id=id map f◦map g=map (f◦g) length (map f xs)=length xs

4 [33]

Grenzen von foldr

I Andere rekursive Struktur über Listen

I Quicksort:baumartigeRekursion q s o r t :: Ord a⇒ [ a ]→ [ a ] q s o r t [ ] = [ ]

q s o r t x s = q s o r t ( f i l t e r (< he ad x s ) x s ) ++

f i l t e r ( h ead x s ==) x s ++

q s o r t ( f i l t e r ( hea d x s <) x s ) I Rekursion nicht über Listenstruktur:

I take: Rekursion überInt t a k e :: I n t→ [ a ]→ [ a ]

t a k e n _ | n≤ 0 = [ ]

t a k e _ [ ] = [ ]

t a k e n ( x : x s ) = x : t a k e ( n−1) x s

I Version mitfoldrdivergiert für nicht-endliche Listen

5 [33]

fold für andere Datentypen

foldist universell

Jeder algebraische DatentypThat genau einfoldr.

I Kanonische Signatur fürT:

IPro KonstruktorCein FunktionsargumentfC IFreie TypvariableβfürT

I Kanonische Definition:

IPro KonstruktorCeine Gleichung

IGleichung wendet FunktionsparameterfCauf Argumente an

data I L = Cons I n t I L | E r r S t r i n g | Mt

f o l d I L :: ( I n t→ ββ)→ ( S t r i n g→ β)→ β→ I L→ β f o l d I L f e a ( Cons i i l ) = f i ( f o l d I L f e a i l ) f o l d I L f e a ( E r r s t r ) = e s t r

f o l d I L f e a Mt = a

6 [33]

fold für bekannte Datentypen

I Bool: Fallunterscheidung:

data B o o l = True | F a l s e f o l d B o o l :: ββ→ B o o l→ β f o l d B o o l a1 a2 True = a1 f o l d B o o l a1 a2 F a l s e = a2 I Maybe a: Auswertung

data Maybe α = N o t h i n g | J u s t α f o l d M a y b e :: β→ (α→ β)→ Maybe α→ β f o l d M a y b e b f N o t h i n g = b

f o l d M a y b e b f ( J u s t a ) = f a

I Alsmaybevordefiniert

fold für bekannte Datentypen

I Tupel: dieuncurry-Funktion

f o l d P a i r :: (α→ βγ)→ (α, β)→ γ f o l d P a i r f ( a , b )= f a b

I Natürliche Zahlen: Iterator

type Nat= I n t −−data Nat = Zero | Succ Nat f o l d N a t :: β→ (β→ β)→ Nat→ β f o l d N a t e f x | x == 0 = e

f o l d N a t e f x | x > 0 = f ( f o l d N a t e f ( x−1))

(2)

fold für binäre Bäume

I Binäre Bäume:

data T r e e α=Mt | Node α ( T r e e α) ( T r e e α)

I Labelnurin den Knoten I Instanzen von Map und Fold:

mapT :: (α→ β)→ T r e e α→ T r e e β mapT f Mt =Mt

mapT f ( Node a l r )=

Node ( f a ) ( mapT f l ) ( mapT f r ) f o l d T :: (α→ βββ)→ β→ T r e e α→ β f o l d T f e Mt= e

f o l d T f e ( Node a l r ) =

f a ( f o l d T f e l ) ( f o l d T f e r )

I Kein (offensichtliches) Filter

9 [33]

Funktionen mit fold und map

I Höhe des Baumes berechnen:

h e i g h t :: T r e e α→ I n t

h e i g h t = f o l d T (λ_ l r→ 1+ l+ r ) 0

I Inorder-Traversion der Knoten:

i n o r d e r :: T r e e α→ [α]

i n o r d e r = f o l d T (λa l r→ l++ [ a ]++ r ) [ ]

10 [33]

Kanonische Eigenschaften von foldT und mapT

I Auch hier gilt:

foldTree Node Mt=id mapTree id=id

mapTree f◦mapTree g=mapTree (f◦g) shape (mapTree f xs)=shape xs

I Mitshape:: Treeα→Tree ()

11 [33]

Das Labyrinth

I Das Labyrinth als variadischer Baum:

data Lab a = Node a [ Lab a ]

I Auch hierfürfoldTundmapT:

f o l d T :: ( a→ [ b ]→ b )→ Lab a→ b

f o l d T f ( Node a n s ) = f a ( map ( f o l d T f ) n s )

mapT :: ( a→ b )→ Lab a→ Lab b

mapT f ( Node a n s ) =Node ( f a ) ( map ( mapT f ) n s )

12 [33]

Suche im Labyrinth

I Tiefensuche viafoldT

d f t s ’ :: Lab a→ [ Path a ] d f t s ’ n = f o l d T add n where

add a [ ] = [ [ a ] ]

add a p s = concatMap ( map ( a : ) ) p s

I Problem:

I foldTterminiertnichtfürzyklischeStruturen

I Auch nicht, wennaddprüft obaschon enthalten ist

13 [33]

Tiefensuche direkt

I Deshalbdirekterekursive Lösung

d f t s :: Eq a⇒ ( Lab a→ B o o l )→ Lab a→ [ Path a ] d f t s t r g = d f t s 0 [ ] where

d f t s 0 p n@ ( Node a n s )

| t r g n = [ r e v e r s e ( a : p ) ]

| e l e m a p = [ ]

| o t h e r w i s e = concatMap ( d f t s 0 ( a : p ) ) n s I Funktioniert füralleLabyrinthe

I Flexible Termination durch Prädikat

IBlätter in gerichteten Graphen i s L e a f ( Node a n s ) = n u l l n s

IBlätter in ungerichteten Graphen

i s U L e a f ( Node a n s ) = n u l l n s | | n u l l ( t a i l n s )

14 [33]

Zusammenfassung map und fold

I mapundfoldsindkanonischeFunktionen höherer Ordnung

I Für jeden Datentyp definierbar

I foldlnur für Listen (linearerDatentyp)

I foldkann beizyklischenArgumenten nicht terminieren

I Problem: Termination vonfoldnurlokalentscheidbar

15 [33]

Funktionen Höherer Ordnung als Entwurfsmethodik

I Kombinationvon Basisoperationen zu komplexen Operationen I KombinatorenalsMusterzur Problemlösung:

IEinfacheBasisoperationen

IWenigeKombinationsoperationen

IAlle anderen Operationenabgeleitet I Kompositionalität:

IGesamtproblem läßt sichzerlegen

IGesamtlösung durchZusammensetzender Einzellösungen

16 [33]

(3)

Kombinatoren im engeren Sinne

Definition (Kombinator)

EinKombinatorist ein punktfrei definierte Funktion höherer Ordnung.

I Herkunft:Kombinatorlogik(Schönfinkel, 1924)

K x y B x S x y z B x z(y z)

I x B x

S,K,IsindKombinatoren

I Fun fact #1: kann alle berechenbaren Funktionen ausdrücken I Fun fact #2:SundKsind genug:I=S K K

17 [33]

Beispiel: Parser

I Parserbilden Eingabe auf Parsierungen ab

IMehrere Parsierungenmöglich

IBacktrackingmöglich I Kombinatoransatz:

IBasisparsererkennenTerminalsymbole

IParserkombinatorenzur Konstruktion:

ISequenzierung(erstA, dannB)

IAlternierung(entwederAoderB)

IAbgeleiteteKombinatoren (z.B.ListenA,nicht-leereListenA+)

18 [33]

Modellierung in Haskell

WelcherTypfür Parser?

typeParse a b = [a]→[(b, [a])]

I Parametrisiert überEingabetyp(Token)aundErgebnisb I Parser übersetztTokeninabstrakte Syntax

I MussRest der Eingabemodellieren I Mussmehrdeutige Ergebnissemodellieren

I Beispiel:"3+4*5" [ (3,"+4*5"), (3+4,"*5"), (3+4*5,"")]

19 [33]

Basisparser

I Erkenntnichts:

none :: P a r s e a b none = c o n s t [ ] I Erkenntalles:

s u c e e d :: b→ P a r s e a b s u c e e d b i n p = [ ( b , i n p ) ] I Erkennteinzelne Token:

s p o t :: ( a→ B o o l )→ P a r s e a a s p o t p [ ] = [ ]

s p o t p ( x : x s ) = i f p x then [ ( x , x s ) ] e l s e [ ] t o k e n :: Eq a⇒ a→ P a r s e a a

t o k e n t = s p o t (λc→ t == c )

IWarum nichtnone,suceeddurchspot? Typ!

20 [33]

Basiskombinatoren: alt, >*>

I Alternierung:

I Erste Alternative wirdbevorzugt i n f i x l 3 ‘ a l t ‘

a l t :: P a r s e a b→ P a r s e a b→ P a r s e a b a l t p1 p2 i = p1 i ++ p2 i

I Sequenzierung:

I Rest des ersten Parsers alsEingabefür den zweiten i n f i x l 5 >∗>

(>∗>) :: P a r s e a b→ P a r s e a c→ P a r s e a ( b , c ) (>∗>) p1 p2 i =

concatMap (λ( b , r )→

map (λ( c , s )→ ( ( b , c ) , s ) ) ( p2 r ) ) ( p1 i )

21 [33]

Basiskombinatoren: use

I mapfür Parser (Rückgabeweiterverarbeiten):

i n f i x 4 ‘ u s e ‘ , ‘ u s e 2 ‘

u s e :: P a r s e a b→ ( b→ c )→ P a r s e a c u s e p f i = map (λ( o , r )→ ( f o , r ) ) ( p i ) u s e 2 :: P a r s e a ( b , c )→ ( b→ c→ d )→ P a r s e a d u s e 2 p f = u s e p ( u n c u r r y f )

I Damit z.B. Sequenzierungrechts/links:

i n f i x l 5 ∗>, >∗

(∗>) :: P a r s e a b→ P a r s e a c→ P a r s e a c (>∗) :: P a r s e a b→ P a r s e a c→ P a r s e a b p1 ∗> p2 = p1 >∗> p2 ‘ u s e ‘ s n d

p1 >∗ p2 = p1 >∗> p2 ‘ u s e ‘ f s t

22 [33]

Abgeleitete Kombinatoren

I Listen: A::=AA|ε l i s t :: P a r s e a b→ P a r s e a [ b ] l i s t p = p>∗> l i s t p ‘ u s e 2 ‘ ( : )

‘ a l t ‘ s u c e e d [ ]

I Nicht-leereListen: A+::=AA some :: P a r s e a b→ P a r s e a [ b ] some p = p>∗> l i s t p ‘ u s e 2 ‘ ( : )

I NB. Präzedenzen:>*>(5) voruse(4) voralt(3)

Verkapselung

I Hauptfunktion:

IEingabe mußvollständigparsiert werden

IAufMehrdeutigkeitprüfen

p a r s e :: P a r s e a b→ [ a ]→ E i t h e r S t r i n g b p a r s e p i =

c a s e f i l t e r ( n u l l . s n d ) $ p i o f

[ ] → L e f t " I n p u t ␣ d o e s ␣ n o t ␣ p a r s e "

[ ( e , _ ) ] → R i g h t e

_ → L e f t " I n p u t ␣ i s ␣ a m b i g u o u s "

I Schnittstelle:

INach außen nur TypParsesichtbar, plusOperationendarauf

(4)

Grammatik für Arithmetische Ausdrücke

Expr ::= Term+Term|Term Term ::= Factor*Factor|Factor Factor ::= Variable|(Expr) Variable ::= Char+

Char ::= a| · · · |z|A| · · · |Z

25 [33]

Abstrakte Syntax für Arithmetische Ausdrücke

I Zur Grammatikabstrakte Syntax data E x p r = P l u s E x p r E x p r

| Times E x p r E x p r

| Var S t r i n g

I Hier UnterscheidungTerm,Factor,Numberunnötig.

26 [33]

Parsierung Arithmetischer Ausdrücke

I Token:Char I Parsierung vonFactor

p F a c t o r :: P a r s e Char E x p r

p F a c t o r =some ( s p o t i s A l p h a ) ‘ u s e ‘ Var

‘ a l t ‘ t o k e n ’ ( ’ ∗> p E x p r >∗ t o k e n ’ ) ’ I Parsierung vonTerm

pTerm :: P a r s e Char E x p r

pTerm =

p F a c t o r >∗ t o k e n ’∗’ >∗> p F a c t o r ‘ u s e 2 ‘ Times

‘ a l t ‘ p F a c t o r I Parsierung vonExpr

p E x p r :: P a r s e Char E x p r

p E x p r =pTerm >∗ t o k e n ’+’ >∗>pTerm ‘ u s e 2 ‘ P l u s

‘ a l t ‘ pTerm

27 [33]

Die Hauptfunktion

I Lexing:Leerzeichenaus der Eingabeentfernen p a r s e E x p r :: S t r i n g→ E x p r

p a r s e E x p r i =

c a s e p a r s e p E x p r ( f i l t e r ( n o t . i s S p a c e ) i ) o f R i g h t e → e

L e f t e r r → e r r o r e r r

28 [33]

Ein kleiner Fehler

I Mangel:a+b+cführt zuSyntaxfehler— Fehler in derGrammatik I Behebung:Änderungder Grammatik

Expr ::= Term+Expr|Term Term ::= Factor*Term|Factor Factor ::= Variable|(Expr) Variable ::= Char+

Char ::= a| · · · |z|A| · · · |Z

I Abstrakte Syntaxbleibt

29 [33]

Änderung des Parsers

I Entsprechende Änderung des Parsers inpTerm pTerm :: P a r s e Char E x p r

pTerm =

p F a c t o r >∗ t o k e n ’∗’ >∗> pTerm ‘ u s e 2 ‘ Times

‘ a l t ‘ p F a c t o r I . . . und inpExpr:

p E x p r :: P a r s e Char E x p r

p E x p r = pTerm >∗ t o k e n ’+’ >∗> p E x p r ‘ u s e 2 ‘ P l u s

‘ a l t ‘ pTerm

I pFactorund Hauptfunktion bleiben.

30 [33]

Erweiterung zu einem Taschenrechner

I Zahlen:

Factor ::= Variable|Number|. . . Number ::= Digit+

Digit ::= 0| · · · |9 I Eine einfacheEingabesprache:

Input ::= !Variable=Expr|$Expr I EineAuswertungsfunktion:

type S t a t e= [ ( S t r i n g , I n t e g e r ) ] e v a l :: S t a t e→ E x p r→ I n t e g e r

r u n :: S t a t e→ S t r i n g→ ( S t a t e , S t r i n g )

31 [33]

Zusammenfassung Parserkombinatoren

I Systematische Konstruktiondes Parsers aus der Grammatik.

I Kompositional:

ILokale Änderung der Grammatik führt zu lokaler Änderung im Parser

IVgl. Parsergeneratoren (yacc/bison, antlr, happy)

I Struktur vonParsezur Benutzung irrelevant

IVorsicht beiMehrdeutigkeitenin der Grammatik (Performance-Falle)

IEinfache Implementierung(wie oben) skaliertnicht

IEffiziente Implementation mitgleicher Schnittstelleauch fürgroße Eingabengeeignet.

32 [33]

(5)

Zusammenfassung

I mapundfoldsind kanonische Funktionen höherer Ordnung I . . . und für alle Datentypen definierbar

I Kombinatoren: Funktionen höherer Ordnung alsEntwurfsmethodik

I EinfacheBasisoperationen

I WenigeabermächtigeKombinationsoperationen

I Reiche Bibliothek anabgeleitetenOperationen

I Nächste Woche: wie prüft man den Typ von (>∗>) p1 p2 i =

concatMap (λ( b , r )→

map (λ( c , s )→ ( ( b , c ) , s ) ) ( p2 r ) ) ( p1 i ) Typinferenz!

33 [33]

Referenzen

ÄHNLICHE DOKUMENTE

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

[r]

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 5 vom 11.11.2014: Funktionen Höherer Ordnung I.