Programmierparadigmen - Einführung in Haskell

Werbung
Einführung
Programmierparadigmen
Einführung in Haskell
D. Rösner
Institut für Wissens- und Sprachverarbeitung
Fakultät für Informatik
Otto-von-Guericke Universität Magdeburg
c
Sommer 2013, 7. April 2013, 2011
- 13 D.Rösner
D. Rösner PGP 2013 . . .
1
Einführung
Gliederung
1
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Listen
Weitere Funktionen
D. Rösner PGP 2013 . . .
2
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Programmiersprache Haskell:
benannt nach Haskell B. Curry
einer der Pioniere des λ-Kalkül
erste Spezifikation der Sprache Ende 80er Jahre
aktuelle Version: Haskell 2010 (davor: Haskell 98)
Download, Tutorials, usw.:
http://www.haskell.org/
einige Bücher (Auswahl):
[Tho11],
[Tho99],
[Bir00]
[CK02]
[Hut06]
...
D. Rösner PGP 2013 . . .
4
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Haskell
interaktive Programmierumgebungen, z.B. WinGHCi
GHC . . . Glasgow Haskell Compiler
frei erhältlicher Interpreter
auch für andere gängige Plattformen
D. Rösner PGP 2013 . . .
5
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Haskell
Elementarer Einstieg
verwende WinGHCi als ’Taschenrechner’
Grundrechenarten:
Addition: +
Subtraktion: Multiplikation: *
Division:
ganzzahlig: ‘div‘
Gleitkomma: /
Exponentiation: ^
Beachte: es gelten die üblichen Vorrangregeln
(Präzedenzregeln)
ansonsten: Verwenden von Klammern
D. Rösner PGP 2013 . . .
6
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
funktionale Programme in Haskell
Definitionen von Funktionen und anderen Werten durch
Gleichungen
Definition assoziiert Namen (Identifikator) mit Wert eines
bestimmten Typs
Syntax:
<name> :: <type>
<name> = <expression>
D. Rösner PGP 2013 . . .
7
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
funktionale Programme in Haskell cont.
lies ‘::’ als ‘hat Typ’ oder ‘ist vom Typ’
Beispiele:
size :: Int
size = 12 + 13
square :: Int -> Int
square n = n * n
D. Rösner PGP 2013 . . .
8
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Haskell – Sprachelemente
Typisierung: jedes Objekt in Haskell hat einen
wohldefinierten Typ
Zweck der Typisierung:
frühzeitiges Erkennen von Programmierfehlern (type
checking)
schon vor Programmausführung (statische Analyse)
D. Rösner PGP 2013 . . .
10
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Haskell – Sprachelemente
vordefinierte elementare Typen (auch Sorten genannt) für
Konstante (= nullstellige Funktionen):
Bool
Int
Char
Float
Integer
Rational
Double
Vorschau: durch Deklaration mit type lassen sich
benutzerdefinierte Typen einführen
D. Rösner PGP 2013 . . .
11
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Zur Unterscheidung zwischen Int und Integer
Zur Klasse Int gehören ganze Zahlen, die sich mit einer
festen Zahl von Bytes darstellen lassen.
der Wert der Variablen maxBound::Int gibt die grösste
als Int darstellbare ganze Zahl an. Dieser Wert ist (bei
WinGHCi) 2147483647.
Will man beliebig grosse ganze Zahlen verarbeiten, so
sollte man den Typ Integer verwenden.
D. Rösner PGP 2013 . . .
12
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Typisierung cont.
Typ von Funktionen (auch Funktionalität genannt) :
Definitions- und Wertebereich durch -> getrennt
angegeben
Beispiel:
double :: Int -> Int
double n = 2*n
bei mehreren Argumenten werden deren Typen durch ->
verbunden
Beispiel: max mit 2 Argumenten aus Int und Wert aus
Int
max :: Int -> Int -> Int
D. Rösner PGP 2013 . . .
13
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Typisierung cont.
Interpretation einer Typdeklaration wie
scale :: Picture -> Int -> Picture
erstens: scale hat zwei Argumente:
das erste ist vom (nutzerdefinierten) Typ Picture,
das zweite vom (vordefinierten) Typ Int
zweitens: das Ergebnis der Anwendung von scale ist vom
Typ Picture
D. Rösner PGP 2013 . . .
14
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
vordefinierte arithmetische Operatoren
+ . . . Summe zweier Zahlen
* . . . Produkt zweier Zahlen
ˆ . . . Exponentiation: 2 ˆ 3 gibt 8
- ...
Differenz, wenn infix verwendet;
umgekehrtes Vorzeichen bei Präfixverwendung (vgl.
negate)
D. Rösner PGP 2013 . . .
15
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
vordefinierte arithmetische Operatoren cont.
div . . . ganzzahlige Division
mod . . . Rest bei ganzzahliger Division (modulo)
abs . . . Absolutbetrag
negate . . . ändere Vorzeichen
D. Rösner PGP 2013 . . .
16
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
vordefinierte Vergleichsoperatoren
für ganze Zahlen, d.h. Typ Int -> Int -> Bool:
>, >=, ==, / =, <=, <
diese Vergleichsoperatoren sind – wie auch die
arithmetischen Operatoren – ‘überladen’ und auch auf
Float anwendbar
Typ dann: Float -> Float -> Bool
für == gilt auch Bool -> Bool -> Bool
bzw. sogar allgemein
t -> t -> Bool
, sofern für den Typ t Gleichheit definiert (Hinweis: t hier
sog. Typvariable)
D. Rösner PGP 2013 . . .
17
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
einige vordefinierte Operatoren bzw. Konstanten für
Float
Name(n)
+ - * /
ˆ
**
exp
log
logBase
pi
signum
sqrt
cos, sin, tan
acos, asin, atan
ceiling, floor, round
fromInt
Typ
Float -> Float -> Float
Float -> Int -> Float
Float -> Float -> Float
Float -> Float
Float -> Float
Float -> Float -> Float
Float
Float -> Float
Float -> Float
Float -> Float
Float -> Float
Float -> Int
Int -> Float
D. Rösner PGP 2013 . . .
Bem.
xn
xy
ex
ln x
loga x
π
Rundung
Konversion
18
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Operatoren
werden infix verwendet, d.h. 3 + 4
aber: Verwendung eines Operatorsymbols <op> in
Präfixposition möglich mit Notation (<op>) , d.h.
(+) 3 4 == 3 + 4
können assoziativ sein; z.B. +, *
nicht-assoziative Operatoren werden festgelegt als
links-assoziativ oder rechts-assoziativ
z.B. - links-assoziativ, d.h.
a - b - c == (a - b) - c
D. Rösner PGP 2013 . . .
19
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Operatoren
Exponentiation ˆ als rechts-assoziativer Operator
*Main> 2 ^3 ^ 3
134217728
*Main> 2 ^(3 ^ 3)
134217728
*Main> (2 ^ 3) ^ 3
512
D. Rösner PGP 2013 . . .
20
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Operatoren
Operatoren haben Bindungsstärke oder Fixität (engl. fixity)
z.B.
* hat Fixität 7,
+ hat 6,
ˆ hat 8,
daher a + b * c == a + (b * c)
und
a ˆ b * c == (a ˆ b) * c
D. Rösner PGP 2013 . . .
21
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Operatoren und Funktionen
Funktionsanwendung hat höchste Bindungsstärke
allgemeine Schreibweise: Funktionsname vor Argument(e)
f v1 v2 ...vn
Beachte: da Funktionsanwendung höhere Bindung als
jeder andere Operator, wird
f n+1
interpretiert als
(f n)+1
für andere Interpretation ist explizite Klammerung
notwendig:
f (n+1)
D. Rösner PGP 2013 . . .
22
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Konversionen von Operatoren und Funktionen
werden Infix-Operatoren in Klammern eingeschlossen, so
können sie als Funktionen vor ihren Argumenten
verwendet werden
Beispiel:
(+) :: Int -> Int -> Int
Verwendung:
(+) a b == a + b
umgekehrt: Funktionen können zu Operatoren gemacht
werden durch Einschluss des Funktionsnamen in sog.
Backquotes
a ‘max‘ b == max a b
D. Rösner PGP 2013 . . .
23
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
zwei Arten von Dateistilen:
Skripte (Extension ‘.hs’):
alles ist Programmtext, sofern nicht explizit als Kommentar
gekennzeichnet
Kommentare bis Zeilenende eingeleitet durch zwei
aufeinanderfolgende ‘-’
Abschnittskommentare zwischen ‘{-’ und ‘-}’
D. Rösner PGP 2013 . . .
25
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
zwei Arten von Dateistilen: cont
literate Skripte (Extension ‘.lhs’):
alles ist Kommentar, sofern nicht am Zeilenanfang durch
‘>’ als Programmzeile gekennzeichnet
literat . . . ‘wörtlich’
D. Rösner PGP 2013 . . .
26
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Beispiel eines Skripts
{... mehrere Zeilen Kommentartext ...
-}
-- Berechnung der Fakultät mit Konditional if
fak :: Int -> Int
fak n = if n == 0 then 1 else n * fak (n - 1)
D. Rösner PGP 2013 . . .
27
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Beispiel eines literaten Skripts
Die Berechnung der Funktion Fakultät ist ein
Standardbeispiel fuer Rekursion.
> fak :: Int -> Int
> fak n = if n == 0 then 1 else n * fak (n - 1)
Eine Variante mit Pattern-Matching:
> fak 0 = 1
> fak n = n * fak (n - 1)
D. Rösner PGP 2013 . . .
28
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Haskell – lexikalische Konventionen
Identifikatoren: Bezeichner von Variablen, von Typen von
Funktionen usw.
Identifikatoren müssen in Haskell mit einem Buchstaben
beginnen
dieser Buchstabe kann gefolgt sein von einer beliebigen
Sequenz von
Buchstaben,
Ziffern,
Unterstrichen (_) und
einzelnen Anführungszeichen (’)
D. Rösner PGP 2013 . . .
30
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Haskell – lexikalische Konventionen
Konventionen für führende Großbuchstaben bzw.
Kleinbuchstaben
alle Namen, die in Definitionen von Werten verwendet
werden (d.h. also auch alle Funktionsnamen), müssen mit
einem kleinen Buchstaben beginnen, ebenso die
Bezeichner für Variable und Typvariable
mit einem Großbuchstaben beginnen Typnamen (z.B. Int),
Konstruktoren, True und False, Modulnamen und auch
die Namen von Typklassen
D. Rösner PGP 2013 . . .
31
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Haskell – lexikalische Konventionen
kleine Sammlung sog. reservierter Wörter
können nicht als Identifikatoren benutzt werden
dazu zählen:
case|class|data|default|deriving|do|else
|if|import|in|infix|infixl|infixr|instance
|let|module|newtype|of|then|type|where|_
D. Rösner PGP 2013 . . .
32
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Haskell – lexikalische Konventionen
Empfehlung: mnemonische, ’sprechende’ Namen
verwenden
z.B.
zinssatz
statt nur z
Empfehlung: bei Namen, die aus mehreren Wörtern
zusammengesetzt sind, den Beginn des zweiten Worts
(und ggf. folgender Wörter) in Großbuchstaben schreiben
z.B. letztesElement
D. Rösner PGP 2013 . . .
33
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Funktionen in Prelude.hs
Prelude.hs enthält viele nützliche Funktionen
D. Rösner PGP 2013 . . .
35
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Listenfunktionen im Prelude:
head
head (x:_)
:: [a] -> a
= x
last
last [x]
last (_:xs)
:: [a] -> a
= x
= last xs
tail
tail (_:xs)
:: [a] -> [a]
= xs
init
init [x]
init (x:xs)
:: [a] -> [a]
= []
= x : init xs
D. Rösner PGP 2013 . . .
36
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Listenfunktionen cont.
null
null []
null (_:_)
:: [a] -> Bool
= True
= False
(++)
[]
++ ys
(x:xs) ++ ys
:: [a] -> [a] -> [a]
= ys
= x : (xs ++ ys)
map
map f xs
:: (a -> b) -> [a] -> [b]
= [ f x | x <- xs ]
filter
filter p xs
:: (a -> Bool) -> [a] -> [a]
= [ x | x <- xs, p x ]
D. Rösner PGP 2013 . . .
37
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Listenfunktionen cont.
concat
concat
:: [[a]] -> [a]
= foldr (++) []
length
length
:: [a] -> Int
= foldl’ (\n _ -> n + 1) 0
(!!)
(x:_)
(_:xs)
(_:_)
[]
!!
!!
!!
!!
:: [a] -> Int -> a
0
= x
n | n>0 = xs !! (n-1)
_
= error "Prelude.!!: negative index"
_
= error "Prelude.!!: index too large"
D. Rösner PGP 2013 . . .
38
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Funktionen in Prelude.hs
Funktionen, die ein Paar als Argument nehmen, vs.
Funktionen mit zwei Argumenten
curry
curry f x y
:: ((a,b) -> c) -> (a -> b -> c)
= f (x,y)
uncurry
uncurry f p
:: (a -> b -> c) -> ((a,b) -> c)
= f (fst p) (snd p)
D. Rösner PGP 2013 . . .
39
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Funktionen in Prelude.hs cont.
id
id
x
:: a -> a
= x
const
const k _
:: a -> b -> a
= k
(.)
(f . g) x
:: (b -> c) -> (a -> b) -> (a -> c)
= f (g x)
flip
flip f x y
:: (a -> b -> c) -> b -> a -> c
= f y x
D. Rösner PGP 2013 . . .
40
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Funktionen in Prelude.hs: Faltung
foldl
:: (a -> b -> a) -> a -> [b] -> a
foldl f z []
= z
foldl f z (x:xs) = foldl f (f z x) xs
foldr
:: (a -> b -> b) -> b -> [a] -> b
foldr f z []
= z
foldr f z (x:xs) = f x (foldr f z xs)
...
D. Rösner PGP 2013 . . .
41
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Funktionen in Prelude.hs
Fehlererzeugung:
primitive error
:: String -> a
Beispiel einer Kontrollstruktur:
until :: (a -> Bool) -> (a -> a) -> a -> a
until p f x
= if p x then x
else until p f (f x)
D. Rösner PGP 2013 . . .
42
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Literatur: I
Richard Bird.
Introduction to functional programming using Haskell.
Prentice Hall Europe, 2000.
ISBN 0-13-484346-0; 2nd edition.
Manual M. Chakravarty and Gabriele C. Keller.
An Introduction to Computing with Haskell.
Pearson Education Australia, 2002.
ISBN 1 74009 404 2; also available in German translation.
Graham Hutton.
Programming in Haskell.
Cambridge University Press, 2006.
ISBN 0521692695.
D. Rösner PGP 2013 . . .
43
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Literatur: II
Simon Thompson.
Haskell - The Craft of Functional Programming.
Addison Wesley Longman Ltd., Essex, 1999.
2nd edition, ISBN 0-201-34275-8; Accompanying Web site:
http://www.cs.ukc.ac.uk/people/staff/sjt/craft2e.
Simon Thompson.
Haskell - the craft of functional programming.
Pearson Education Ltd., Essex, 2011.
3rd edition, ISBN 978-0-201-88295-7; Accompanying Web
site: http://www.haskellcraft.com.
D. Rösner PGP 2013 . . .
44
Herunterladen