• Keine Ergebnisse gefunden

Rekursive Datentypen

N/A
N/A
Protected

Academic year: 2022

Aktie "Rekursive Datentypen"

Copied!
4
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

Rev. 1935 1 [27]

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 [27]

Inhalt

I RekursiveDatentypen

I RekursiveDefinition

I . . . und wozu sie nützlich sind

I Rekursive Datentypen in anderen Sprachen

I Fallbeispiel: Labyrinthe

3 [27]

Der Allgemeine Fall: Algebraische Datentypen

Definition einesalgebraischen DatentypenT:

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

. . .

| Cntn,1. . .tn,kn

I KonstruktorenC1, . . . ,Cnsinddisjunkt:

Cix1. . .xn=Cjy1. . .ym−→i=j I Konstruktorensindinjektiv:

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

∀x∈T.x=Ciy1. . .ym Diese Eigenschaften machenFallunterscheidungmöglich.

Heute:Rekursion

4 [27]

Rekursive Datentypen

I Der definierte TypTkannrechtsbenutzt werden.

I Rekursive Datentypen sindunendlich

I Entsprichtinduktiver Definition

I ModelliertAggregation(Sammlung von Objekten)

I Funktionen werden durchRekursiondefiniert

5 [27]

Algebraische Datentypen: Nomenklatur

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

. . .

| Cntn,1. . .tn,kn

I CisindKonstruktoren(vordefiniert) I Selektorensind Funktionenseli,j:

seli,j(Citi,1. . .ti,ki) =ti,j IPartiell, linksinvers zu Konstruktor

IKönnen vordefiniert werden (erweiterte Syntax derdataDeklaration) I Diskriminatorensind Funktionendisi:

disi ::T→Bool

disi(Ci. . .) =True

disi_ =False

IDefinitionsbereichsbereich des Selektorsseli INie vordefiniert

6 [27]

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

7 [27]

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

8 [27]

(2)

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 )

9 [27]

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

10 [27]

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

11 [27]

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

12 [27]

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 ; }

13 [27]

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 ;

}

14 [27]

Fallbeispiel: Zyklische Datenstrukturen

Quelle: docs.gimp.org

15 [27]

Modellierung des Labyrinths

I Ein Labyrinth ist entweder

Ieine Sackgasse,

Iein Weg, oder

Ieine 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

16 [27]

(3)

Traversion des Labyrinths

I Ziel:Pfadzu einem gegebenZielfinden

I BenötigtPfadeund eine Strategie

data Path = Cons I d Path

| Mt

data Trav = Succ Path

| F a i l

17 [27]

Traversionsstrategie

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

Ian SackgasseFail

Ian Passagen weiterlaufen

Ian 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

18 [27]

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) )

19 [27]

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 ) )

20 [27]

Traversion mit Zyklen

I VeränderteStrategie: Pfad bis hierher übergeben

I WennaktuellerKnoten 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

21 [27]

Zusammenfassung Labyrinth

I Labyrinth−→GraphoderBaum I In Haskell: gleicher Datentyp I Referenzen nichtexplizitin Haskell

IKeineundefiniertenReferenzen (erhöhteProgrammsicherheit)

IKeineGleichheitauf Referenzen

IGleichheit istimmerstrukturell (oderselbstdefiniert)

22 [27]

Beispiel: Zeichenketten selbstgemacht

I EineZeichenketteist

I entwederleer(das leere Wort)

I oder einZeichencund 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

23 [27]

Rekursive Definition

I Typisches Muster:Fallunterscheidung

IEinFallproKonstruktor

I Hier:

ILeereZeichenkette

INichtleereZeichenkette

24 [27]

(4)

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 )

25 [27]

Was haben wir gesehen?

I StrukturellähnlicheTypen:

IEinkaufswagen,Path,MyString(Listen-ähnlich)

IResultat,Preis,Trav(Punktierte Typen) I ÄhnlicheFunktionendarauf

I Besser:eineTypdefinition mit Funktionen, instantiierung zu verschiedenen Typen

Nächste Vorlesung

26 [27]

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)

27 [27]

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 10 vom 20.12.2016: Aktionen und ZuständeI. Christoph Lüth Universität Bremen

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..

Praktische Informatik 3: Funktionale Programmierung Vorlesung 3 vom 28.10.2014: Rekursive Datentypen.. Christoph Lüth Universität Bremen

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

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