Programmieren in Haskell

Werbung
Programmieren in
Haskell
Stefan
Janssen
Programmieren in Haskell
Typen in Haskell
Allgemeines
zu Typen
Vordefinierte
Datentypen
Listen
Stefan Janssen
Universität Bielefeld
AG Praktische Informatik
October 15, 2014
Typen in Haskell
Haskell verwendet strong typing:
Jeder Wert hat einen Typ; Funktionen dürfen nur auf
Argumente des richtigen Typs angewandt werden
Typen können vom Compiler geprüft werden
Typisierung kostet keinen Rechenaufwand zur Laufzeit
Programmieren in
Haskell
Stefan
Janssen
Allgemeines
zu Typen
Vordefinierte
Datentypen
Listen
Typen in Haskell
Haskell verwendet strong typing:
Jeder Wert hat einen Typ; Funktionen dürfen nur auf
Argumente des richtigen Typs angewandt werden
Typen können vom Compiler geprüft werden
Typisierung kostet keinen Rechenaufwand zur Laufzeit
Haskell verwendet parametrischen Typ-Polymorphismus
Funktionen können allgemeine Typen mit Typ-Parametern
haben; z.B.
map:: (a -> b) -> [a] -> [b]
Bei der Anwendung einer polymorphen Funktion
konkretisiert sich ihr Typ
Haskell verwendet Typ-Klassen – davon später mehr.
Programmieren in
Haskell
Stefan
Janssen
Allgemeines
zu Typen
Vordefinierte
Datentypen
Listen
Datentypen
Programmieren in
Haskell
Ein Datentyp ist eine Mengen von Werten, worauf Operationen
(Funktionen) definiert werden können.
eingebaute Datentypen sind vordefiniert und haben oft
eine besondere Notation
benutzerdefinierte Datentypen werden durch
Typdefinitionen eingeführt; haben Standard-Notation
Typdeklarationen geben zu neuen Namen den Typ ihres
Werts an
Typdeklarationen sind optional. Sie dienen hauptsächlich der
Lesbarkeit.
Stefan
Janssen
Allgemeines
zu Typen
Vordefinierte
Datentypen
Listen
Funktionstypen
1
Der wichtigste Datentyp ist die Funktion, allgemein
a -> b
Programmieren in
Haskell
Stefan
Janssen
Allgemeines
zu Typen
Vordefinierte
Datentypen
Listen
Funktionstypen
1
1
2
3
4
Der wichtigste Datentyp ist die Funktion, allgemein
a -> b
Konkrete Funktionen haben speziellere Typen, z.B.
> power :: Int -> Int -> Int
> isqrt :: Int -> Float
> id ::
a -> a
> id x =
x
Programmieren in
Haskell
Stefan
Janssen
Allgemeines
zu Typen
Vordefinierte
Datentypen
Listen
Funktionstypen
1
1
2
3
4
1
2
Der wichtigste Datentyp ist die Funktion, allgemein
a -> b
Konkrete Funktionen haben speziellere Typen, z.B.
> power :: Int -> Int -> Int
> isqrt :: Int -> Float
> id ::
a -> a
> id x =
x
Mehrstellige Funktionen und Funktionen höherer Ordnung
ergeben sich, wenn man für a und b selbst wieder
Funktionstypen einsetzt
> (+):: Int -> Int -> Int
> (:):: a -> [ a ] -> [ a ]
3
4
> map :: (a - > b ) -> [ a ] -> [ b ]
map ist also eine zweistellige Funktion, deren erstes Argument
selbst eine Funktion ist
Programmieren in
Haskell
Stefan
Janssen
Allgemeines
zu Typen
Vordefinierte
Datentypen
Listen
Gestaffelte Funktionen
Programmieren in
Haskell
Stefan
Janssen
1
1
1
Mehrstelligen Funktionen gibt man den “gestaffelten” Typ
a -> b -> c ... -> y -> z
-- 25 - stellig
was (per Definition von ->) das Gleiche ist wie
a -> ( b -> ( c ...( y -> z )...))
aber etwas anderes als
(a ,b ,c ,... , y ) -> z
Das letzte wäre eine 1-stellige Funktion mit einem 25-Tupel als
Argument.
Allgemeines
zu Typen
Vordefinierte
Datentypen
Listen
Eingebaute Datentypen: Zahlen
Programmieren in
Haskell
Elementare eingebaute Datentypen in Haskell sind:
Ganze Zahlen (Integer, Int)
Funktionen darauf sind z.B.: +, -, *, div, mod, ^
Fließkommazahlen (Float, Double)
+, /, ^, sqrt
Konstanten können mehreren Typen angehören:
Wert
mögl. Typen
1, -5, 100, 0.314e1 Int, Integer, Float, Double
2.0, 2e3, 3.14e0
Float, Double
1,-5, 120
Int, Integer
Integer sind ganze Zahlen beliebiger Stellenzahl
Stefan
Janssen
Allgemeines
zu Typen
Vordefinierte
Datentypen
Listen
Typklasse
Num
Fractional
Integral
Eingebaute Datentypen: Bool, Char, String
Programmieren in
Haskell
Stefan
Janssen
Wahrheitswerte (Bool): True, False
&&, ||, not
Allgemeines
zu Typen
Zeichen (Char): ’a’, ’A’, ’\’ ...
Vordefinierte
Datentypen
Zeichenketten (String), wobei String = [Char]
"abraham", "2XG5", "" ...
Listen
Listen ([a])
[], :, ++, reverse, take, drop
Listen sind polymorph und kommen gleich noch ausführlicher!
Typen von Ausdrücken
Programmieren in
Haskell
Ausdrücke haben Typen:
Stefan
Janssen
1
2
3
4
5
6
7
8
9
42
:: Int
3 + 4
:: Int
4.2
:: Float
True
:: Bool
" Hallo Welt ! " :: String -- bzw . [ Char ]
[1 ,2 ,3]
:: [ Int ]
[]
:: [ a ]
[[]]
:: [[ a ]]
Hier sind einige Typen spezieller als es sein muss!
Allgemeines
zu Typen
Vordefinierte
Datentypen
Listen
Typinferenz in Ausdrücken
Programmieren in
Haskell
Stefan
Janssen
Hugs> :t (1+2)
1 + 2 :: Num a => a
Hugs> :t (4.2)
4.2 :: Fractional a => a
Hugs> :t 2/3
2 / 3 :: Fractional a => a
Klasse => ... nennt man einen Typkontext
Allgemeines
zu Typen
Vordefinierte
Datentypen
Listen
Typen einschränken
Durch explizite Typ-Angaben kann man den allgemeinsten Typ
einschränken:
Programmieren in
Haskell
Stefan
Janssen
Hugs> 2 / 3
0.6666666666666
Allgemeines
zu Typen
Hier wird für 1 und 2 ein Typ der Klasse Fractional a
abgeleitet. Jetzt die Einschränkung:
Hugs> (2::Int)
ERROR - Cannot
*** Instance
*** Expression
/ (3::Int)
infer instance
: Fractional Int
: 2 / 3
Vordefinierte
Datentypen
Listen
Typen einschränken
Durch explizite Typ-Angaben kann man den allgemeinsten Typ
einschränken:
Programmieren in
Haskell
Stefan
Janssen
Hugs> 2 / 3
0.6666666666666
Allgemeines
zu Typen
Hier wird für 1 und 2 ein Typ der Klasse Fractional a
abgeleitet. Jetzt die Einschränkung:
Hugs> (2::Int)
ERROR - Cannot
*** Instance
*** Expression
/ (3::Int)
infer instance
: Fractional Int
: 2 / 3
Hugs> (2::Int) ‘div‘ (3::Int)
0
Vordefinierte
Datentypen
Listen
Typklassen
In Haskell sind Typen in Klassen organisiert. Typen sind dabei
Instanzen von Klassen.
Programmieren in
Haskell
Stefan
Janssen
Allgemeines
zu Typen
Vordefinierte
Datentypen
Listen
Typklassen
In Haskell sind Typen in Klassen organisiert. Typen sind dabei
Instanzen von Klassen.
Beispiele für Typklassen
Eq Überprüfung auf Gleichheit. In der Klasse Eq sind die
Operationen == und /= definiert.
Instanzen z.B.: Int, Float, Double, String
Programmieren in
Haskell
Stefan
Janssen
Allgemeines
zu Typen
Vordefinierte
Datentypen
Listen
Typklassen
In Haskell sind Typen in Klassen organisiert. Typen sind dabei
Instanzen von Klassen.
Beispiele für Typklassen
Eq Überprüfung auf Gleichheit. In der Klasse Eq sind die
Operationen == und /= definiert.
Instanzen z.B.: Int, Float, Double, String
Ord Ordnungsrelation. In der Klasse Ord sind die Operationen
<,>,<=,>= definiert.
Instanzen z.B.: Int, Float, Double, String
Programmieren in
Haskell
Stefan
Janssen
Allgemeines
zu Typen
Vordefinierte
Datentypen
Listen
Typklassen
In Haskell sind Typen in Klassen organisiert. Typen sind dabei
Instanzen von Klassen.
Beispiele für Typklassen
Eq Überprüfung auf Gleichheit. In der Klasse Eq sind die
Operationen == und /= definiert.
Instanzen z.B.: Int, Float, Double, String
Ord Ordnungsrelation. In der Klasse Ord sind die Operationen
<,>,<=,>= definiert.
Instanzen z.B.: Int, Float, Double, String
Num Umfasst die numerischen Typen, z.B. Int, Float, Double
Operationen: +,-,*
Programmieren in
Haskell
Stefan
Janssen
Allgemeines
zu Typen
Vordefinierte
Datentypen
Listen
Typklassen
In Haskell sind Typen in Klassen organisiert. Typen sind dabei
Instanzen von Klassen.
Beispiele für Typklassen
Eq Überprüfung auf Gleichheit. In der Klasse Eq sind die
Operationen == und /= definiert.
Instanzen z.B.: Int, Float, Double, String
Ord Ordnungsrelation. In der Klasse Ord sind die Operationen
<,>,<=,>= definiert.
Instanzen z.B.: Int, Float, Double, String
Num Umfasst die numerischen Typen, z.B. Int, Float, Double
Operationen: +,-,*
Show Werte eines Typs der Instanz der Klasse Show ist, lassen
sich ausgeben
Z.B. Int, Float, Double, String
Programmieren in
Haskell
Stefan
Janssen
Allgemeines
zu Typen
Vordefinierte
Datentypen
Listen
Definition von Typklassen
Programmieren in
Haskell
Stefan
Janssen
Natürlich kann man selbst
Typklassen neu definieren (später in Einheit 16)
bestehende Typklassen erweitern
konkrete Datentypen zu Instanzen von Typklassen machen
Das entspricht in etwa den abstrakten Klassen oder Interfaces
in Java, die durch konkrete Klassen implementiert werden.
Allgemeines
zu Typen
Vordefinierte
Datentypen
Listen
Tupel-Typen
Notation ( a1, a2, a3, ... )
vordefinierte Funktionen:
fst
snd
...
Komponenten können verschiedene Typen haben
vs. Liste
Programmieren in
Haskell
Stefan
Janssen
Allgemeines
zu Typen
Vordefinierte
Datentypen
Listen
Tupel-Typen
Notation ( a1, a2, a3, ... )
vordefinierte Funktionen:
fst
snd
...
Komponenten können verschiedene Typen haben
vs. Liste
Example
1
2
fst
:: (a , b ) -> a
fst (x , y ) = x
3
4
5
snd
:: (a , b ) -> b
snd (_ , y ) = y
Programmieren in
Haskell
Stefan
Janssen
Allgemeines
zu Typen
Vordefinierte
Datentypen
Listen
Void
Programmieren in
Haskell
Stefan
Janssen
Allgemeines
zu Typen
Unit-Datentyp in Haskell: ()
Vordefinierte
Datentypen
einziges Element: ()
Listen
vergleichbar mit void in C/Java
Listen in der funktionalen Programmierung
Programmieren in
Haskell
Listen gibt es in allen Programmiersprachen, aber in der
funktionalen Programmierung werden sie besonders viel
benutzt.
Dafür gibt es
einen polymorphen Datentyp für Listen aus Elementen von
beliebigem, aber gleichem Typ
viele vordefinierte Funktionen auf Listen
eine spezielle Notation für Listen,
Listenbeschreibungen ähnlich der mathematischen
Mengen-Notation
Stefan
Janssen
Allgemeines
zu Typen
Vordefinierte
Datentypen
Listen
Der polymorphe Listen-Typ [a]
Notation:
[1,2,3,4] – geschönte Notation
1:2:3:4:[] – Standard-Notation mit Konstruktoren
Programmieren in
Haskell
Stefan
Janssen
Allgemeines
zu Typen
Vordefinierte
Datentypen
Listen
Der polymorphe Listen-Typ [a]
Notation:
[1,2,3,4] – geschönte Notation
1:2:3:4:[] – Standard-Notation mit Konstruktoren
(:) :: a -> [a] -> [a]
”Cons”
[] :: [a]
”Nil”
Programmieren in
Haskell
Stefan
Janssen
Allgemeines
zu Typen
Vordefinierte
Datentypen
Listen
Der polymorphe Listen-Typ [a]
Notation:
[1,2,3,4] – geschönte Notation
1:2:3:4:[] – Standard-Notation mit Konstruktoren
(:) :: a -> [a] -> [a]
”Cons”
[] :: [a]
”Nil”
[1..10]
Typ-Notation: [a], [Int] usw.
Programmieren in
Haskell
Stefan
Janssen
Allgemeines
zu Typen
Vordefinierte
Datentypen
Listen
Der polymorphe Listen-Typ [a]
Notation:
[1,2,3,4] – geschönte Notation
1:2:3:4:[] – Standard-Notation mit Konstruktoren
(:) :: a -> [a] -> [a]
”Cons”
[] :: [a]
”Nil”
[1..10]
Typ-Notation: [a], [Int] usw.
Main> 1:2:3:4:[]
[1,2,3,4]
Programmieren in
Haskell
Stefan
Janssen
Allgemeines
zu Typen
Vordefinierte
Datentypen
Listen
Der polymorphe Listen-Typ [a]
Notation:
[1,2,3,4] – geschönte Notation
1:2:3:4:[] – Standard-Notation mit Konstruktoren
(:) :: a -> [a] -> [a]
”Cons”
[] :: [a]
”Nil”
[1..10]
Typ-Notation: [a], [Int] usw.
Main> 1:2:3:4:[]
[1,2,3,4]
Example
1
2
3
> length ’
:: [ a ] -> Int
> length ’ []
= 0
> length ’ ( a : as ) = 1 + length ’ as
Programmieren in
Haskell
Stefan
Janssen
Allgemeines
zu Typen
Vordefinierte
Datentypen
Listen
Listenbeschreibungen
Programmieren in
Haskell
1
2
3
4
Listenbeschreibungen sind der mathematischen
Stefan
Mengen-Notation nachempfunden.
Janssen
Beispiel:
Allgemeines
sm =
[ x | x <- " abraham " , x < ’i ’]
zu Typen
pairs =
[( a , b +1) | a <- " aber " , b <- [1 ,2 ,3]]
Vordefinierte
Datentypen
evenodd = [( a ,b , a + b ) | a <- [1..10] , b <- [11..20]
,
Listen
even a == odd b ]
Listenbeschreibungen
Programmieren in
Haskell
1
2
3
4
1
2
Listenbeschreibungen sind der mathematischen
Stefan
Mengen-Notation nachempfunden.
Janssen
Beispiel:
Allgemeines
sm =
[ x | x <- " abraham " , x < ’i ’]
zu Typen
pairs =
[( a , b +1) | a <- " aber " , b <- [1 ,2 ,3]]
Vordefinierte
Datentypen
evenodd = [( a ,b , a + b ) | a <- [1..10] , b <- [11..20]
,
Listen
even a == odd b ]
Allgemeine Form:
[ f x y ... | x <- X , cond x ,
y <- Y , cond x y , ...]
X, Y, ...: Listen, aus denen Elemente kommen
cond:
Bedingungen, die diese erfuellen muessen
f x y ...: Elemente der neuen Listen, die aus den
ausgewaehlten x, y,... berechnet werden
Listenbeschreibungen für Zahlenfolgen
Programmieren in
Haskell
1
2
3
4
5
6
Besonders komfortable Notation gibt es für Zahlenfolgen:
l1 = [1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,10]
l2 = [1..10]
l3 = [1..]
l4 = [1 ,5..42]
l5 = [1 ,5 ..]
l6 = [10 ,8 .. 1]
Aufsteigende und absteigende Zahlenfolgen;
die Differenz der beiden ersten Zahlen gibt die Schrittweite und
Richtung an,
.. bedeutet Fortsetzung, bis zum Endwert wenn angegeben,
sonst unendlich.
Stefan
Janssen
Allgemeines
zu Typen
Vordefinierte
Datentypen
Listen
Mehr über Listen
Programmieren in
Haskell
Stefan
Janssen
Allgemeines
zu Typen
Es folgen viele Beispiele von Funktionen über Listen.
Siehe Datei listintro.lhs
Vordefinierte
Datentypen
Listen
Herunterladen