Praktische Informatik 3: Funktionale Programmierung Vorlesung 4 vom 06.11.2012: Typvariablen und Polymorphie
Christoph Lüth Universität Bremen Wintersemester 2012/13
Rev. 1861 1 [28]
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 [28]
Inhalt
I Letzte Vorlesung: rekursive Datentypen
I Diese Vorlesung:
I Abstraktionüber Typen:TypvariablenundPolymorphie
I Arten der Polymorphie:
I Parametrische Polymorphie
I Ad-hoc Polymorphie
3 [28]
Ähnliche Datentypen der letzten Vorlesung
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 data E i n k a u f s w a g e n =
L e e r e r W a g e n
| 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 data Path = Cons I d Path
| Mt data M y S t r i n g =Empty
| Cons Char M y S t r i n g I einkonstanterKonstruktor
I einlinear rekursiverKonstruktor
4 [28]
Ähnliche Funktionen der letzten Vorlesung
I Pfade:
c a t :: Path→ Path→ Path c a t Mt p= p
c a t ( Cons p p s ) q s = Cons p ( c a t p s q s ) r e v :: Path→ Path
r e v Mt=Mt
r e v ( Cons p p s ) = c a t ( r e v p s ) ( Cons p Mt ) I Zeichenketten:
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 ) 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 )
5 [28]
Ähnliche Funktionen der letzten Vorlesung
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 i n v e n t u r :: L a g e r→ I n t
i n v e n t u r L e e r e s L a g e r =0
i n v e n t u r ( L a g e r a m l ) = c e n t a m+ i n v e n t u r l 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 ein Fall pro Konstruktor
I linearerrekursiver Aufruf
6 [28]
Die Lösung: Polymorphie
Definition (Polymorphie)
Polymorphie istAbstraktion über Typen
Arten der Polymorphie
I ParametrischePolymorphie (Typvariablen):
Generisch überalleTypen I Ad-HocPolymorphie (Überladung):
Nur fürbestimmteTypen
7 [28]
Parametrische Polymorphie: Typvariablen
I Typvariablenabstrahieren über Typen data L i s t α =Empty
| Cons α ( L i s t α) I αist eineTypvariable
I αkann mitIdoderCharinstantiiertwerden I List αist einpolymorpherDatentyp I Typvariableαwird bei Anwendung instantiiert I Signaturder Konstruktoren
Empty :: L i s t α
Cons :: α→ L i s t α→ L i s t α
8 [28]
Polymorphe Ausdrücke
I TypkorrekteTerme: Typ
Empty Listα
Cons 57 Empty List Int
Cons 7 (Cons 8 Empty) List Int
Cons ’p’ (Cons ’i’ (Cons ’3’ Empty)) List Char
Cons True Empty List Bool
I Nichttyp-korrekt:
Cons ’a’ (Cons 0 Empty) Cons True (Cons ’x’ Empty) wegenSignaturdes Konstruktors:
Cons :: α→ L i s t α→ L i s t α
9 [28]
Polymorphe Funktionen
I Parametrische Polymorphie fürFunktionen:
c a t :: L i s t α → L i s t α → L i s t α
c a t Empty y s = y s
c a t ( Cons x x s ) y s =Cons x ( c a t x s y s ) I Typvariableαwird bei Anwendung instantiiert:
c a t ( Cons 3 Empty ) ( Cons 5 ( Cons 57 Empty ) ) c a t ( Cons ’ p ’ ( Cons ’ i ’ Empty ) ) ( Cons ’ 3 ’ Empty ) abernicht
c a t ( Cons True Empty ) ( Cons ’ a ’ ( Cons 0 Empty ) ) I Typvariable: vergleichbar mit Funktionsparameter
I Restriktion: Typvariable auf Resultatposition?
10 [28]
Beispiel: Der Shop (refaktoriert)
I EinkaufswagenundLagerals Listen:
type L a g e r = [ ( A r t i k e l , Menge ) ]
type E i n k a u f s w a g e n = [ ( A r t i k e l , Menge ) ] I GleicherTyp!
I Bug or Feature?
I Lösung: Datentypverkapseln
data L a g e r = L a g e r [ ( A r t i k e l , Menge ) ] d e r i v i n g ( Eq , Show )
data 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 [ ( A r t i k e l , Menge ) ] d e r i v i n g ( Eq , Show )
11 [28]
Tupel
I Mehr alseineTypvariable möglich I Beispiel:Tupel(kartesisches Produkt, Paare)
data P a i r α β = P a i r α β I Signatur des Konstruktors:
P a i r :: α→ β→ P a i r α β
I Beispielterm Typ
Pair 4 ’x’ Pair Int Char
Pair (Cons True Empty) ’a’ Pair (List Bool) Char Pair (3+ 4) (Cons ’a’ Empty) Pair Int (List Char) Cons (Pair 7 ’x’) Empty List (Pair Int Char)
12 [28]
Vordefinierte Datentypen: Tupel und Listen
I Eingebautersyntaktischer Zucker I Tupelsind das kartesische Produkt
data (α, β) = (α, β)
I (a, b)=alle Kombinationenvon Werten ausaundb
I Auch n-Tupel:(a,b,c)etc.
I Listen
data [α] = [ ] | α : [α]
I WeitereAbkürzungen:[x]= x:[],[x,y] = x:y:[]etc.
13 [28]
Vordefinierte Datentypen: Optionen
data P r e i s = Cent I n t | U n g u e l t i g
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
data Trav = Succ Path
| F a i l
Instanzen einesvordefiniertenTypen:
data Maybe α= J u s t α | N o t h i n g Vordefinierten Funktionen (import Data.Maybe):
f r o m J u s t :: Maybe α → α
fromMaybe :: α→ Maybe α→ α
m a y b e T o L i s t :: Maybe α→ [α]
l i s t T o M a y b e :: [α]→ Maybe α −−“sicheres” head
14 [28]
Übersicht: vordefinierte Funktionen auf Listen I
(++) :: [α]→ [α]→ [α] −−Verketten
( ! ! ) :: [α]→ I n t→ α −−n-tes Element selektieren c o n c a t :: [ [α] ]→ [α] −−“flachklopfen”
l e n g t h :: [α]→ I n t −−Länge
head , l a s t :: [α]→ α −−Erstes/letztes Element t a i l , i n i t :: [α]→ [α] −−Hinterer/vorderer Rest r e p l i c a t e :: I n t→ α→ [α] −−ErzeugenKopien t a k e :: I n t→ [α]→ [α] −−ErstenElemente d r o p :: I n t→ [α]→ [α] −−Rest nachnElementen s p l i t A t :: I n t→ [α]→ ( [α] , [α] )−−Spaltet an Indexn
r e v e r s e :: [α]→ [α] −−Dreht Liste um
z i p :: [α]→ [β]→ [ (α, β) ] −−Erzeugt Liste v. Paaren u n z i p :: [ (α, β) ]→ ( [α] , [β] ) −−Spaltet Liste v. Paaren and , o r:: [ B o o l ]→ B o o l −−Konjunktion/Disjunktion
sum :: [ I n t ]→ I n t −−Summe (überladen)
p r o d u c t:: [ I n t ]→ I n t −−Produkt (überladen)
15 [28]
Vordefinierte Datentypen: Zeichenketten
I Stringsind Listen von Zeichen:
type S t r i n g = [ Char ]
I Alle vordefiniertenFunktionen auf Listenverfügbar.
I Syntaktischer Zuckerzur Eingabe:
" yoho " == [ ’ y ’ , ’ o ’ , ’ h ’ , ’ o ’ ] == ’ y ’ : ’ o ’ : ’ h ’ : ’ o ’ : [ ] I Beispiel:
c n t :: Char→ S t r i n g→ I n t
c n t c [ ] = 0
c n t c ( x : x s ) = i f ( c== x ) then 1+ c n t c x s e l s e c n t c x s
16 [28]
Zurück im Labyrinth
I Labyrinth als Instanz eines allgemeineren Datentyps?
I Ja:variadischeBäume
data Lab = Node I d [ Lab ] type Path = [ I d ]
type Trav =Maybe Path
17 [28]
Labyrinth verallgemeinert: Variadische Bäume
I VariableAnzahl Kinderknoten:Listevon Kinderknoten data VTree α= Node α [ VTree α]
I Anzahl Knoten zählen:
c o u n t :: VTree α→ I n t
c o u n t ( VNode _ n s ) =1+ c o u n t _ n o d e s n s
c o u n t _ n o d e s :: [ VTree α] → I n t c o u n t _ n o d e s [ ] =0
c o u n t _ n o d e s ( t : t s ) = c o u n t t+ c o u n t _ n o d e s t s
18 [28]
Ad-Hoc Polymorphie und Overloading
Definition (Überladung)
Funktionf:: a→bexistiert fürmehr als einen, abernichtfüralleTypen I
I Beispiel:
I Gleichheit:(==)::a→a→Bool
I Vergleich:(<)::a→a→Bool
I Anzeige:show::a→String I Lösung:Typklassen I Typklassen bestehen aus:
I Deklarationder Typklasse
I Instantiierungfür bestimmte Typen
19 [28]
Typklassen: Syntax
I Deklaration:
c l a s s Show a where show :: a→ S t r i n g I Instantiierung:
i n s t a n c e Show B o o l where show True = " Wahr "
show F a l s e = " F a l s c h "
I Prominente vordefinierte Typklassen
IEqfür(==)
IOrdfür(<)(und andere Vergleiche)
IShowfürshow
INum(uvm) für numerische Operationen (Literale überladen)
20 [28]
Typklassen in polymorphen Funktionen
I Element einer Liste (vordefiniert):
e l e m :: Eq α ⇒ α→ [α]→ B o o l e l e m e [ ] = F a l s e
e l e m e ( x : x s ) = e == x | | e l e m e x s
I Sortierung einer List:qsort
q s o r t :: Ord α ⇒ [α]→ [α]
I Liste ordnen und anzeigen:
s h o w s o r t e d :: ( Eq α, Show α)⇒ [α]→ S t r i n g s h o w s o r t e d x =show ( q s o r t x )
21 [28]
Hierarchien von Typklassen
I Typklassen können anderevoraussetzen:
c l a s s Eq α⇒ Ord α where (<) :: α→ α→ B o o l (≤) :: α→ α→ B o o l a ≤b = a == b | | a < b
I Default-Definition von<=
I Kann bei Instantiierung überschrieben werden
22 [28]
Polymorphie: the missing link
Parametrisch Ad-Hoc
Funktionen f :: α→Int class Fαwhere
f :: a→Int
Typen dataMaybeα=
Justα| Nothing
Konstruktorklassen
I KannEntscheidbarkeitder Typherleitung gefährden
I Erstmalnicht relevant
23 [28]
Polymorphie in anderen Programmiersprachen: Java
I Polymorphie inJava: Methode auf alle Subklassen anwendbar
IManuelleTypkonversionnötig, fehleranfällig I Neu ab Java 1.5:Generics
IDamitparametrische Polymorphiemöglich c l a s s A b s L i s t<T> {
p u b l i c A b s L i s t (T e l , A b s L i s t<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 T e l e m ;
p u b l i c A b s L i s t<T> n e x t ;
24 [28]
Polymorphie in anderen Programmiersprachen: Java
Typkorrekte Konkatenenation:
v o i d c o n c a t ( A b s L i s t<T> o ) {
A b s L i s t<T> c u r= t h i s;
w h i l e ( c u r . n e x t 6= n u l l) c u r= c u r . n e x t ; c u r . n e x t= o ;
}
Nachteil:Benutzung umständlich, weil keine Typherleitung A b s L i s t<I n t e g e r> l=
new A b s L i s t<I n t e g e r>(new I n t e g e r ( 1 ) ,
new A b s L i s t<I n t e g e r>(new I n t e g e r ( 2 ) , n u l l) ) ;
25 [28]
Polymorphie in anderen Programmiersprachen: Java
I Ad-Hoc Polymorphie:Interfaceundabstrakte Klassen
I Flexibler in Java: beliebige Parameter etc.
26 [28]
Polymorphie in anderen Programmiersprachen: C
I “Polymorphie” in C:void * s t r u c t l i s t {
v o i d ∗he ad ;
s t r u c t l i s t ∗t a i l ; }
I Gegeben:
i n t x = 7 ;
s t r u c t l i s t s = { &x , NULL } ; I s.headhat Typvoid *:
i n t y ;
y= ∗( i n t ∗) s . hea d ;
I Nicht möglich:headdirekt als Skalar (e.g.int) I C++:Templates
27 [28]
Zusammenfassung
I Abstraktionüber Typen
IUniformeAbstraktion: Typvariable, parametrische Polymorphie
IFallbasierteAbstraktion: Überladung, ad-hoc-Polymorphie I In der Sprache:
ITypklassen
Ipolymorphe Funktionen und Datentypen I Vordefinierte Typen: Listen[a]und Tupel(a,b) I Nächste Woche: Abstraktion über Funktionen
Funktionen höherer Ordnung
28 [28]