Praktische Informatik 3: Einführung in die Funktionale Programmierung
Vorlesung vom 17.11.2010: Typvariablen und Polymorphie
Christoph Lüth & Dennis Walter
Universität Bremen
Wintersemester 2010/11
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
2 [26]
Inhalt
I Letzte Vorlesung: rekursive Datentypen
I Diese Vorlesung:
I Abstraktionüber Typen:TypvariablenundPolymorphie
Zeichenketten und Listen von Zahlen
I Letzte VL: EineZeichenketteist
I entwederleer(das leere Wort)
I oder einZeichenund eine weitereZeichenkette data M y S t r i n g = Empty
| Cons Char M y S t r i n g
I EineListe von Zahlen ist
I entwederleer
I oder eineZahlund eine weitereListe data I n t L i s t = Empty
| Cons I n t I n t L i s t
I Strukturellgleiche Definition
Zwei Instanzen einerallgemeineren Definition.
4 [26]
Zeichenketten und Listen von Zahlen
I Letzte VL: EineZeichenketteist
I entwederleer(das leere Wort)
I oder einZeichenund eine weitereZeichenkette data M y S t r i n g = Empty
| Cons Char M y S t r i n g
I EineListe von Zahlen ist
I entwederleer
I oder eineZahlund eine weitereListe data I n t L i s t = Empty
| Cons I n t I n t L i s t
I Strukturellgleiche Definition
Zwei Instanzen einerallgemeineren Definition.
Zeichenketten und Listen von Zahlen
I Letzte VL: EineZeichenketteist
I entwederleer(das leere Wort)
I oder einZeichenund eine weitereZeichenkette data M y S t r i n g = Empty
| Cons Char M y S t r i n g
I EineListe von Zahlen ist
I entwederleer
I oder eineZahlund eine weitereListe data I n t L i s t = Empty
| Cons I n t I n t L i s t
I Strukturellgleiche Definition
Zwei Instanzeneinerallgemeineren Definition.
4 [26]
Typvariablen
I Typvariablenabstrahieren über Typen data L i s t α = Empty
| Cons α ( L i s t α)
I α ist eineTypvariable
I α kann mitChar oderIntinstantiiert werden
I List α ist ein polymorpherDatentyp
I Typvariableα wird bei Anwendung instantiiert
I Signaturder Konstruktoren Empty :: L i s t α
Cons :: α→ L i s t α→ L i s t α
Polymorphe Datentypen
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) wegenSignatur des Konstruktors: Cons :: α→ L i s t α→ L i s t α
6 [26]
Polymorphe Datentypen
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) wegenSignatur des Konstruktors: Cons :: α→ L i s t α→ L i s t α
Polymorphe Datentypen
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) wegenSignatur des Konstruktors: Cons :: α→ L i s t α→ L i s t α
6 [26]
Polymorphe Datentypen
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) wegenSignatur des Konstruktors: Cons :: α→ L i s t α→ L i s t α
Polymorphe Datentypen
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) wegenSignatur des Konstruktors: Cons :: α→ L i s t α→ L i s t α
6 [26]
Polymorphe Datentypen
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) wegenSignatur des Konstruktors: Cons :: α→ L i s t α→ L i s t α
Polymorphe Datentypen
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) wegenSignatur des Konstruktors: Cons :: α→ L i s t α→ L i s t α
6 [26]
Polymorphe Datentypen
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) wegenSignatur des Konstruktors: Cons :: α→ L i s t α→ L i s t α
Polymorphe Datentypen
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) wegenSignatur des Konstruktors: Cons :: α→ L i s t α→ L i s t α
6 [26]
Polymorphe Datentypen
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) wegenSignatur des Konstruktors:
Cons :: α→ L i s t α→ L i s t α
Polymorphe Funktionen
I Verkettung vonMyString:
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 Verkettung vonIntList:
c a t :: I n t L i s t→ I n t L i s t→ I n t L i s t
c a t Empty t = t
c a t ( Cons c s ) t = Cons c ( c a t s t )
I GleicheDefinition, unterschiedlicherTyp
Zwei Instanzen einerallgemeineren Definition.
7 [26]
Polymorphe Funktionen
I Verkettung vonMyString:
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 Verkettung vonIntList:
c a t :: I n t L i s t→ I n t L i s t→ I n t L i s t
c a t Empty t = t
c a t ( Cons c s ) t = Cons c ( c a t s t )
I GleicheDefinition, unterschiedlicherTyp
Zwei Instanzen einerallgemeineren Definition.
Polymorphe Funktionen
I Verkettung vonMyString:
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 Verkettung vonIntList:
c a t :: I n t L i s t→ I n t L i s t→ I n t L i s t
c a t Empty t = t
c a t ( Cons c s ) t = Cons c ( c a t s t )
I GleicheDefinition, unterschiedlicherTyp
Zwei Instanzeneinerallgemeineren Definition.
7 [26]
Polymorphe Funktionen
I Polymorphie auch 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
Polymorphe Datentypen: Bäume
Datentyp:
data BTree α = MtBTree
| BNode α ( BTree α) ( BTree α) Höhe des Baumes:
h e i g h t :: BTree α→ I n t h e i g h t MtBTree = 0
h e i g h t ( BNode j l r ) = max ( h e i g h t l ) ( h e i g h t r )+ 1 Traversion — erzeugtListe ausBaum:
i n o r d e r :: BTree α→ L i s t α i n o r d e r MtBTree = Empty i n o r d e r ( BNode j l r ) =
c a t ( i n o r d e r l ) ( Cons j ( i n o r d e r r ) )
9 [26]
Tupel
I Mehr alseineTypvariable möglich
I Beispiel:Tupel (kartesisches Produkt, Paare)
data P a i r α b = P a i r α b
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)
Tupel
I Mehr alseineTypvariable möglich
I Beispiel:Tupel (kartesisches Produkt, Paare)
data P a i r α b = P a i r α b
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)
10 [26]
Tupel
I Mehr alseineTypvariable möglich
I Beispiel:Tupel (kartesisches Produkt, Paare)
data P a i r α b = P a i r α b
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)
Tupel
I Mehr alseineTypvariable möglich
I Beispiel:Tupel (kartesisches Produkt, Paare)
data P a i r α b = P a i r α b
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)
10 [26]
Tupel
I Mehr alseineTypvariable möglich
I Beispiel:Tupel (kartesisches Produkt, Paare)
data P a i r α b = P a i r α b
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)
Tupel
I Mehr alseineTypvariable möglich
I Beispiel:Tupel (kartesisches Produkt, Paare)
data P a i r α b = P a i r α b
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)
10 [26]
Tupel
I Mehr alseineTypvariable möglich
I Beispiel:Tupel (kartesisches Produkt, Paare)
data P a i r α b = P a i r α b
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)
Tupel
I Mehr alseineTypvariable möglich
I Beispiel:Tupel (kartesisches Produkt, Paare)
data P a i r α b = P a i r α b
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)
10 [26]
Tupel
I Mehr alseineTypvariable möglich
I Beispiel:Tupel (kartesisches Produkt, Paare)
data P a i r α b = P a i r α b
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)
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.
11 [26]
Ü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→ α→ [α] −−Erzeugen Kopien t a k e :: I n t→ [α]→ [α] −−Erste n Elemente d r o p :: I n t→ [α]→ [α] −−Rest nachn Elementen 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)
Zeichenketten: String
I Stringsind Listen von Zeichen:
type S t r i n g = [ Char ]
I Alle vordefiniertenFunktionen auf Listenverfügbar.
I Syntaktischer Zuckerzur Eingabe:
[ ’ y ’ , ’ o ’ , ’ h ’ , ’ o ’ ] == " yoho "
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
13 [26]
Variadische Bäume
I VariableAnzahl Kinderknoten:Liste von Kinderknoten data VTree α = MtVTree
| VNode α [ VTree α]
I Anzahl Knoten zählen:
c o u n t :: VTree α→ I n t c o u n t MtVTree = 0
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
Berechnungsmuster für Listen
I
I Primitiv rekursiveDefinitionen:
I EineGleichung für leere Liste
I EineGleichung für nicht-leere Liste,rekursiverAufruf
I Komprehensionsschema:
I JedesElementder Eingabeliste
I wirdgetestet
I und gegebenfallstransformiert
15 [26]
Listenkomprehension
I Ein einfachesBeispiel: Zeichenkette in Kleinbuchstaben wandeln t o L :: S t r i n g→ S t r i n g
t o L s = [ t o L o w e r c | c ← s ]
I Buchstabenherausfiltern:
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 s = [ c | c ← s , i s A l p h a c ]
I Kombination: alle Buchstaben kanonisch kleingeschrieben t o L L :: S t r i n g→ S t r i n g
t o L L s = [ t o L o w e r c | c← s , i s A l p h a c ]
Listenkomprehension
I AllgemeineForm:
[ E c | c ← L , t e s t c ]
I Ergebnis:E cfür alle WertecinL, so dasstest cwahr ist
I Typen:L :: [α],c :: α, test :: α→Bool,E :: α→β, Ergebnis [β]
I Auchmehrere Generatoren und Tests möglich:
[ E c1 . . . cn | c1← L1 , t e s t 1 c1 ,
c2← L2 c1 , t e s t 2 c1 c2 , . . .]
I Evom Typα1→α2. . .→β
17 [26]
Variadische Bäume II
I Die Zähl-Funktion vereinfacht:
c o u n t ’ :: VTree α→ I n t c o u n t ’ MtVTree = 0 c o u n t ’ ( VNode _ t s ) =
1+ sum [ c o u n t ’ t | t← t s ]
I Die Höhe:
h e i g h t ’ :: VTree α→ I n t h e i g h t ’ MtVTree = 0 h e i g h t ’ ( VNode _ t s ) =
1+ maximum ( 0 : [ h e i g h t ’ t | t← t s ] )
Beispiel: Permutation von Listen
perms :: [α] → [ [α] ]
I Permutation derleeren Liste
I Permutation vonx:xs
I xan allen Stellen in alle Permutationen vonxs eingefügt.
perms [ ] = [ [ ] ] −−- Wichtig!
perms ( x : x s ) = [ p s ++ [ x ] ++ q s
| r s ← perms x s ,
( ps , q s ) ← s p l i t s r s ]
I Dabeisplits: alle möglichen Aufspaltungen s p l i t s :: [α] → [ ( [α] , [α] ) ] s p l i t s [ ] = [ ( [ ] , [ ] ) ] s p l i t s ( y : y s ) = ( [ ] , y : y s ) :
[ ( y : ps , q s ) | ( ps , q s ) ← s p l i t s y s ]
19 [26]
Beispiel: Quicksort
I Zerlege Liste in Elemente kleiner, gleich und größer dem ersten,
I sortiere Teilstücke,
I konkateniere Ergebnisse.
q s o r t :: [α]→ [α] q s o r t [ ] = [ ] q s o r t ( x : x s ) =
q s o r t s m a l l e r ++ x : e q u a l s ++ q s o r t l a r g e r where s m a l l e r = [ y | y ← x s , y < x ]
e q u a l s = [ y | y ← x s , y == x ] l a r g e r = [ y | y ← x s , y > x ]
Beispiel: Quicksort
I Zerlege Liste in Elemente kleiner, gleich und größer dem ersten,
I sortiere Teilstücke,
I konkateniere Ergebnisse.
q s o r t :: [α]→ [α] q s o r t [ ] = [ ] q s o r t ( x : x s ) =
q s o r t s m a l l e r ++ x : e q u a l s ++ q s o r t l a r g e r where s m a l l e r = [ y | y ← x s , y < x ]
e q u a l s = [ y | y ← x s , y == x ] l a r g e r = [ y | y ← x s , y > x ]
20 [26]
Überladung und Polymorphie
I Fehler:qsortnur für Datentypen mitVergleichsfunktion
I Überladung: Funktion f:: a→b existiert für einige, abernichtfür alle Typen
I Beispiel:
I Gleichheit:(==)::a→a→Bool
I Vergleich:(<) :: a→a→Bool
I Anzeige:show :: a→ String
I Lösung:Typklassen
I TypklasseEqfür (==)
I TypklasseOrdfür (<)(und andere Vergleiche)
I TypklasseShow fürshow
I AuchAd-hoc Polymorphie(im Ggs. zur parametrischen Polymorpie)
Typklassen in polymorphen Funktionen
I qsort, korrekte Signatur:
q s o r t :: Ord α ⇒ [α]→ [α]
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 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 )
22 [26]
Polymorphie in anderen Programmiersprachen: Java
I Polymorphie inJava: Methode auf alle Subklassen anwendbar
I ManuelleTypkonversionnötig, fehleranfällig
I Neu ab Java 1.5:Generics
I Damitparametrische 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 ;
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 ) ) ;
24 [26]
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 Typ void *:
i n t y ;
y= ∗( i n t ∗) s . hea d ;
I Nicht möglich:head direkt als Skalar (e.g.int)
Zusammenfassung
I Typvariablenund (parametrische)Polymorphie:Abstraktion über Typen
I Vordefinierte Typen: Listen[a] und Tupel(a,b)
I Berechungsmusterüber Listen:primitive Rekursion, Listenkomprehension
I Überladungdurch Typklassen
I Nächste Woche: Funktionen höherer Ordnung
26 [26]