• Keine Ergebnisse gefunden

Praktische Informatik 3: Funktionale Programmierung Vorlesung 3 vom 30.10.2012: Rekursive Datentypen

N/A
N/A
Protected

Academic year: 2022

Aktie "Praktische Informatik 3: Funktionale Programmierung Vorlesung 3 vom 30.10.2012: Rekursive Datentypen"

Copied!
29
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

Praktische Informatik 3: Funktionale Programmierung Vorlesung 3 vom 30.10.2012: Rekursive Datentypen

Christoph Lüth

Universität Bremen

Wintersemester 2012/13

(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

I Funktionen höherer Ordnung II

I Typinferenz

I Teil II: Funktionale Programmierung im Großen

I Teil III: Funktionale Programmierung im richtigen Leben

(3)

Inhalt

I RekursiveDatentypen

I RekursiveDefinition

I . . . und wozu sie nützlich sind

I Rekursive Datentypen in anderen Sprachen

I Fallbeispiel: Labyrinthe

(4)

Der Allgemeine Fall: Algebraische Datentypen

Definition eines algebraischen DatentypenT:

data T = C1t1,1. . .t1,k1 . . .

| Cntn,1. . .tn,kn

I KonstruktorenC1, . . . ,Cn sind disjunkt:

Ci x1. . .xn=Cj y1. . .ym−→i =j

I Konstruktorensindinjektiv:

C x1. . .xn=C y1. . .yn−→xi =yi I Konstruktorenerzeugenden Datentyp:

∀x ∈T.x =Ci y1. . .ym

Diese Eigenschaften machen Fallunterscheidungmöglich.

Heute:Rekursion

(5)

Rekursive Datentypen

I Der definierte TypT kannrechtsbenutzt werden.

I Rekursive Datentypen sindunendlich

I Entsprichtinduktiver Definition

I ModelliertAggregation(Sammlung von Objekten)

I Funktionen werden durchRekursiondefiniert

(6)

Algebraische Datentypen: Nomenklatur

Gegeben Definition

data T = C1t1,1. . .t1,k1 . . .

| Cntn,1. . .tn,kn

I Ci sind Konstruktoren(vordefiniert)

I Selektorensind Funktionenseli,j: seli,j (Ci ti,1. . . ti,ki) =ti,j

I Partiell, linksinvers zu Konstruktor

I Können vordefiniert werden (erweiterte Syntax derdataDeklaration)

I Diskriminatorensind Funktionendisi:

disi ::T→Bool

disi (Ci. . .) =True

disi _ =False

I Definitionsbereichsbereich des Selektorsseli I Nie vordefiniert

(7)

Uncle Bob’s Auld Time Grocery Shoppe Revisited

I Ein Lager für Bob’s Shoppe:

I entweder leer

I oder es enthält Artikel und Menge, und weiteres

data L a g e r = L e e r e s L a g e r

| L a g e r A r t i k e l Menge L a g e r

(8)

Suchen im Lager

I Rekursive Suche:

s u c h e :: A r t i k e l→ L a g e r→ R e s u l t a t s u c h e a r t ( L a g e r l a r t m l )

| a r t == l a r t = G e f u n d e n m

| o t h e r w i s e = s u c h e a r t l

s u c h e a r t L e e r e s L a g e r = N i c h t g e f u n d e n

I Resultat:

data R e s u l t a t = G e f u n d e n Menge | N i c h t g e f u n d e n

(9)

Einlagern

I Mengen sollen aggregiert werden, e.g. 35l Milch und 20l Milch werden 55l Milch

e i n l a g e r n :: A r t i k e l→ Menge→ L a g e r→ L a g e r e i n l a g e r n a m l =

l e t h i n e i n a m L e e r e s L a g e r = L a g e r a m L e e r e s L a g e r h i n e i n a m ( L a g e r a l ml l )

| a == a l = L a g e r a ( a d d i e r e m ml ) l

| o t h e r w i s e = L a g e r a l ml ( h i n e i n a m l ) i n c a s e p r e i s a m o f

U n g u e l t i g → l _ → h i n e i n a m l

a d d i e r e ( S t u e c k i ) ( S t u e c k j )= S t u e c k ( i+ j ) a d d i e r e ( Gramm g ) ( Gramm h ) = Gramm ( g+ h ) a d d i e r e ( L i t e r l ) ( L i t e r m) = L i t e r ( l+ m)

a d d i e r e m n = e r r o r ( " a d d i e r e : ␣ "++ show m++ " ␣ und ␣ "++ show n )

(10)

Einkaufen und bezahlen

I Artikel einkaufen:

e i n k a u f :: A r t i k e l→ Menge→ E i n k a u f s w a g e n→ E i n k a u f s w a g e n e i n k a u f a m e =

c a s e p r e i s a m o f U n g u e l t i g → e _ → E i n k a u f a m e

I Gesamtsumme berechnen:

k a s s e :: E i n k a u f s w a g e n→ I n t k a s s e L e e r e r W a g e n = 0

k a s s e ( E i n k a u f a m e ) = c e n t a m+ k a s s e e

(11)

Beispiel: Kassenbon

k a s s e n b o n :: E i n k a u f s w a g e n→ S t r i n g Ausgabe:

Bob’s Aulde Grocery Shoppe

Artikel Menge Preis

---

Schinken 50 g. 0.99 EU

Milch Bio 1.0 l. 1.19 EU

Schinken 50 g. 0.99 EU

Apfel Boskoop 3 St 1.65 EU

=====================================

Summe: 4.82 EU

Unveränderlicher Kopf

Ausgabe von Artikel und Mange (rekur- siv)

Ausgabe vonkasse

(12)

Kassenbon: Implementation

I Kernfunktion:

a r t i k e l :: E i n k a u f s w a g e n→ S t r i n g a r t i k e l L e e r e r W a g e n = " "

a r t i k e l ( E i n k a u f a m e ) = f o r m a t L 20 ( show a ) ++

f o r m a t R 7 ( menge m) ++

f o r m a t R 10 ( showEuro ( c e n t a m) ) ++ " \n "++

a r t i k e l e

I Hilfsfunktionen:

f o r m a t L :: I n t→ S t r i n g→ S t r i n g f o r m a t R :: I n t→ S t r i n g→ S t r i n g showEuro :: I n t→ S t r i n g

(13)

Rekursive Typen in Java

I Nachbildung durch Klassen, z.B. für Listen:

c l a s s L i s t {

p u b l i c L i s t ( O b j e c t e l , L i s t t l ) { t h i s . e l e m= e l ;

t h i s . n e x t= t l ; }

p u b l i c O b j e c t e l e m ; p u b l i c L i s t n e x t ;

I Länge (iterativ):

i n t l e n g t h ( ) { i n t i= 0 ;

f o r ( L i s t c u r= t h i s; c u r != n u l l ; c u r= c u r . n e x t ) i++;

r e t u r n i ; }

(14)

Rekursive Typen in C

I C: Produkte, Aufzählungen, keine rekursiven Typen

I Rekursion durchZeiger

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 ;

I Konstruktorennutzerimplementiert l i s t c o n s (v o i d ∗hd , l i s t t l ) { l i s t l ;

i f ( ( l= ( l i s t ) m a l l o c (s i z e o f(s t r u c t l i s t _ t ) ) )== NULL ) { p r i n t f ( " Out ␣ o f ␣memory \n " ) ; e x i t (−1 ) ;

}

l→ e l e m= hd ; l→ n e x t= t l ; r e t u r n l ;

}

(15)

Fallbeispiel: Zyklische Datenstrukturen

Quelle: docs.gimp.org

(16)

Modellierung des Labyrinths

I Ein Labyrinth ist entweder

I eine Sackgasse,

I ein Weg, oder

I eine Abzweigung in zwei Richtungen.

data Lab = Dead I d

| P a s s I d Lab

| TJnc I d Lab Lab

I Ferner benötigt: eindeutigeBezeichnerder Knoten type I d = I n t

(17)

Traversion des Labyrinths

I Ziel:Pfadzu einem gegebenZiel finden

I BenötigtPfadeund eine Strategie data Path = Cons I d Path

| Mt

data Trav = Succ Path

| F a i l

(18)

Traversionsstrategie

I An jedem Knoten prüfen, ob Ziel erreicht, ansonsten

I an SackgasseFail

I an Passagen weiterlaufen

I an Kreuzungen Auswahl treffen

I erfordert Propagation vonFail:

c o n s :: I d→ Trav→ Trav s e l e c t :: Trav→ Trav→ Trav

I Geht vonzyklenfreienLabyrinth aus

(19)

Zyklenfreie Traversion

t r a v e r s e 1 :: I d→ Lab→ Trav t r a v e r s e 1 t ( Dead i )

| i == t = Succ ( Cons i Mt )

| o t h e r w i s e = F a i l t r a v e r s e 1 t ( P a s s i l )

| t == i = Succ ( Cons i Mt )

| o t h e r w i s e = c o n s i ( t r a v e r s e 1 t l ) t r a v e r s e 1 t ( TJnc i l m)

| t == i = Succ ( Cons i Mt )

| o t h e r w i s e = s e l e c t ( c o n s i ( t r a v e r s e 1 t l ) ) ( c o n s i ( t r a v e r s e 1 t m) )

(20)

Traversion mit Zyklen

t r a v e r s e 2 :: I d→ Lab→ Path→ Trav t r a v e r s e 2 t ( Dead i ) p

| i == t = Succ ( r e v ( Cons i p ) )

| o t h e r w i s e = F a i l t r a v e r s e 2 t ( P a s s i l ) p

| c o n t a i n s i p = F a i l

| t == i = Succ ( r e v ( Cons i p ) )

| o t h e r w i s e = t r a v e r s e 2 t l ( Cons i p ) t r a v e r s e 2 t ( TJnc i l m) p

| c o n t a i n s i p = F a i l

| t == i = Succ ( r e v ( Cons i p ) )

| o t h e r w i s e = s e l e c t ( t r a v e r s e 2 t l ( Cons i p ) ) ( t r a v e r s e 2 t m ( Cons i p ) )

(21)

Traversion mit Zyklen

I VeränderteStrategie: Pfad bis hierher übergeben

I Wennaktueller Knoten in bisherigen Pfadenthaltenist,Fail

I Ansonsten wie oben

I Neue Hilfsfunktionen

c o n t a i n s :: I d→ Path→ B o o l r e v :: Path→ Path

(22)

Zusammenfassung Labyrinth

I Labyrinth−→Graph oder Baum

I In Haskell: gleicher Datentyp

I Referenzen nichtexplizitin Haskell

I KeineundefiniertenReferenzen (erhöhte Programmsicherheit)

I KeineGleichheitauf Referenzen

I Gleichheit istimmerstrukturell (oderselbstdefiniert)

(23)

Beispiel: Zeichenketten selbstgemacht

I EineZeichenketteist

I entwederleer(das leere Wort)

I oder einZeichenc und eine weitereZeichenkettexs data M y S t r i n g = Empty

| Cons Char M y S t r i n g

I LineareRekursion

I Genau ein rekursiver Aufruf

(24)

Rekursive Definition

I Typisches Muster:Fallunterscheidung

I EinFallproKonstruktor

I Hier:

I LeereZeichenkette

I NichtleereZeichenkette

(25)

Funktionen auf Zeichenketten

I Länge:

l e n :: M y S t r i n g→ I n t

l e n Empty = 0

l e n ( Cons c s t r ) = 1+ l e n s t r

I Verkettung:

c a t :: M y S t r i n g→ M y S t r i n g→ M y S t r i n g

c a t Empty t = t

c a t ( Cons c s ) t = Cons c ( c a t s t )

I Umkehrung:

r e v :: M y S t r i n g→ M y S t r i n g

r e v Empty = Empty

r e v ( Cons c t ) = c a t ( r e v t ) ( Cons c Empty )

(26)

Funktionen auf Zeichenketten

I Länge:

l e n :: M y S t r i n g→ I n t

l e n Empty = 0

l e n ( Cons c s t r ) = 1+ l e n s t r

I Verkettung:

c a t :: M y S t r i n g→ M y S t r i n g→ M y S t r i n g

c a t Empty t = t

c a t ( Cons c s ) t = Cons c ( c a t s t )

I Umkehrung:

r e v :: M y S t r i n g→ M y S t r i n g

r e v Empty = Empty

r e v ( Cons c t ) = c a t ( r e v t ) ( Cons c Empty )

(27)

Funktionen auf Zeichenketten

I Länge:

l e n :: M y S t r i n g→ I n t

l e n Empty = 0

l e n ( Cons c s t r ) = 1+ l e n s t r

I Verkettung:

c a t :: M y S t r i n g→ M y S t r i n g→ M y S t r i n g

c a t Empty t = t

c a t ( Cons c s ) t = Cons c ( c a t s t )

I Umkehrung:

r e v :: M y S t r i n g→ M y S t r i n g

r e v Empty = Empty

r e v ( Cons c t ) = c a t ( r e v t ) ( Cons c Empty )

(28)

Was haben wir gesehen?

I StrukturellähnlicheTypen:

I Einkaufswagen,Path,MyString(Listen-ähnlich)

I Resultat,Preis,Trav(Punktierte Typen)

I ÄhnlicheFunktionendarauf

I Besser:eineTypdefinition mit Funktionen, instantiierung zu verschiedenen Typen

Nächste Vorlesung

(29)

Zusammenfassung

I Datentypen könnenrekursivsein

I Rekursive Datentypen sindunendlich(induktiv)

I Funktionen werdenrekursivdefiniert

I Fallbeispiele: Einkaufen in Bob’s Shoppe, Labyrinthtraversion

I Viele strukturell ähnliche Typen

I NächsteWoche: Abstraktion über Typen (Polymorphie)

Referenzen

ÄHNLICHE DOKUMENTE

I Für funktionale Programme: rekursiv definierte Funktionen.. Äquivalenz von operationaler und

Ein abstrakter Datentyp (ADT) besteht aus einem (oder mehreren) Typen und Operationen darauf, mit folgenden Eigenschaften:. I Werte des Typen können nur über die

Praktische Informatik 3: Funktionale Programmierung Vorlesung 2 vom 21.10.2014: Funktionen und Datentypen..

contains :: Id→ Path→ Bool cat :: Path→ Path→ Path snoc :: Path→ Id → Path..

I Werte des Typen können nur über die bereitgestellten Operationen erzeugt werden. I Eigenschaften von Werten des Typen werden nur über die bereitgestellten

Praktische Informatik 3: Funktionale Programmierung Vorlesung 10 vom 18.12.2012: Spezifikation und Beweis..

konstanter Aufwand ←→ beliebige Genauigkeit, wachsender Aufwand Haskell bietet die Auswahl:. I Int - ganze Zahlen als Maschinenworte (≥

I Werte des Typen können nur über die bereitgestellten Operationen erzeugt werden. I Eigenschaften von Werten des Typen werden nur über die bereitgestellten