Programmierparadigmen - Einführung in Haskell

Werbung
Einführung
Einführung
Gliederung
Programmierparadigmen
Einführung in Haskell
1
D. Rösner
Institut für Wissens- und Sprachverarbeitung
Fakultät für Informatik
Otto-von-Guericke Universität Magdeburg
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Listen
Weitere Funktionen
c
Sommer 2011, 4. April 2011, 2011
D.Rösner
D. Rösner PGP 2011 . . .
Einführung
1
D. Rösner PGP 2011 . . .
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Einführung
Programmiersprache Haskell:
2
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Haskell
benannt nach Haskell B. Curry
einer der Pioniere des λ-Kalkül
erste Spezifikation der Sprache Ende 80er Jahre
interaktive Programmierumgebungen, z.B. WinGHCi
aktuelle Version: Haskell 98
GHC . . . Glasgow Haskell Compiler
frei erhältlicher Interpreter
auch für andere gängige Plattformen
Download, Tutorials, usw.: http://www.haskell.org/
einige Bücher (Auswahl):
[Tho99],
[Bir00]
[CK02]
[Hut06]
D. Rösner PGP 2011 . . .
4
D. Rösner PGP 2011 . . .
5
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Einführung
Haskell
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
funktionale Programme in Haskell
Elementarer Einstieg
verwende WinGHCi als ’Taschenrechner’
Grundrechenarten:
Definitionen von Funktionen und anderen Werten durch
Gleichungen
Addition: +
Subtraktion: Multiplikation: *
Division:
Definition assoziiert Namen (Identifikator) mit Wert eines
bestimmten Typs
Syntax:
ganzzahlig: ‘div‘
Gleitkomma: /
<name> :: <type>
<name> = <expression>
Exponentiation: ^
Beachte: es gelten die üblichen Vorrangregeln
(Präzedenzregeln)
ansonsten: Verwenden von Klammern
D. Rösner PGP 2011 . . .
Einführung
6
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
D. Rösner PGP 2011 . . .
Einführung
funktionale Programme in Haskell cont.
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Haskell – Sprachelemente
lies ‘::’ als ‘hat Typ’ oder ‘ist vom Typ’
Beispiele:
Typisierung: jedes Objekt in Haskell hat einen
wohldefinierten Typ
size :: Int
size = 12 + 13
Zweck der Typisierung:
frühzeitiges Erkennen von Programmierfehlern (type
checking)
schon vor Programmausführung (statische Analyse)
square :: Int -> Int
square n = n * n
D. Rösner PGP 2011 . . .
7
8
D. Rösner PGP 2011 . . .
10
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Einführung
Haskell – Sprachelemente
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Zur Unterscheidung zwischen Int und Integer
vordefinierte elementare Typen (auch Sorten genannt) für
Konstante (= nullstellige Funktionen):
Zur Klasse Int gehören ganze Zahlen, die sich mit einer
festen Zahl von Bytes darstellen lassen.
Bool
Int
Char
Float
Integer
Rational
Double
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.
Vorschau: durch Deklaration mit type lassen sich
benutzerdefinierte Typen einführen
D. Rösner PGP 2011 . . .
Einführung
D. Rösner PGP 2011 . . .
11
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Einführung
Typisierung cont.
12
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Typisierung cont.
Typ von Funktionen (auch Funktionalität genannt) :
Definitions- und Wertebereich durch -> getrennt
angegeben
Interpretation einer Typdeklaration wie
scale :: Picture -> Int -> Picture
erstens: scale hat zwei Argumente:
Beispiel:
double :: Int -> Int
double n = 2*n
das erste ist vom (nutzerdefinierten) Typ Picture,
das zweite vom (vordefinierten) Typ Int
bei mehreren Argumenten werden deren Typen durch ->
verbunden
zweitens: das Ergebnis der Anwendung von scale ist vom
Typ Picture
Beispiel: max mit 2 Argumenten aus Int und Wert aus
Int
max :: Int -> Int -> Int
D. Rösner PGP 2011 . . .
13
D. Rösner PGP 2011 . . .
14
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Einführung
vordefinierte arithmetische Operatoren
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
vordefinierte arithmetische Operatoren cont.
+ . . . Summe zweier Zahlen
div . . . ganzzahlige Division
* . . . Produkt zweier Zahlen
ˆ . . . Exponentiation: 2 ˆ 3 gibt 8
- ...
mod . . . Rest bei ganzzahliger Division (modulo)
abs . . . Absolutbetrag
Differenz, wenn infix verwendet;
umgekehrtes Vorzeichen bei Präfixverwendung (vgl.
negate)
D. Rösner PGP 2011 . . .
Einführung
negate . . . ändere Vorzeichen
D. Rösner PGP 2011 . . .
15
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Einführung
vordefinierte Vergleichsoperatoren
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
einige vordefinierte Operatoren bzw. Konstanten für
Float
für ganze Zahlen, d.h. Typ Int -> Int -> Bool:
>, >=, ==, / =, <=, <
Name(n)
+ - * /
ˆ
**
exp
log
logBase
pi
signum
sqrt
cos, sin, tan
acos, asin, atan
ceiling, floor, round
fromInt
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 2011 . . .
16
17
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 2011 . . .
Bem.
xn
xy
ex
ln x
loga x
π
Rundung
Konversion
18
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Einführung
Operatoren
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Operatoren
werden infix verwendet, d.h. 3 + 4
Exponentiation ˆ als rechts-assoziativer Operator
aber: Verwendung eines Operatorsymbols <op> in
Präfixposition möglich mit Notation (<op>) , d.h.
(+) 3 4 == 3 + 4
*Main> 2 ^3 ^ 3
134217728
*Main> 2 ^(3 ^ 3)
134217728
*Main> (2 ^ 3) ^ 3
512
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 2011 . . .
Einführung
19
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
D. Rösner PGP 2011 . . .
Einführung
Operatoren
20
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Operatoren und Funktionen
Funktionsanwendung hat höchste Bindungsstärke
allgemeine Schreibweise: Funktionsname vor Argument(e)
f v1 v2 ...vn
Operatoren haben Bindungsstärke oder Fixität (engl. fixity)
z.B.
Beachte: da Funktionsanwendung höhere Bindung als
jeder andere Operator, wird
f n+1
interpretiert als
(f n)+1
* 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 2011 . . .
für andere Interpretation ist explizite Klammerung
notwendig:
f (n+1)
21
D. Rösner PGP 2011 . . .
22
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Einführung
Konversionen von Operatoren und Funktionen
zwei Arten von Dateistilen:
werden Infix-Operatoren in Klammern eingeschlossen, so
können sie als Funktionen vor ihren Argumenten
verwendet werden
Skripte (Extension ‘.hs’):
alles ist Programmtext, sofern nicht explizit als Kommentar
gekennzeichnet
Beispiel:
(+) :: Int -> Int -> Int
Beispiel:Verwendung:
(+) a b == a + b
Kommentare bis Zeilenende eingeleitet durch zwei
aufeinanderfolgende ‘-’
Abschnittskommentare zwischen ‘{-’ und ‘-}’
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 2011 . . .
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
D. Rösner PGP 2011 . . .
23
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Einführung
zwei Arten von Dateistilen: cont
25
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Beispiel eines Skripts
{... mehrere Zeilen Kommentartext ...
-}
-- Berechnung der Fakultät mit Konditional if
literate Skripte (Extension ‘.lhs’):
alles ist Kommentar, sofern nicht am Zeilenanfang durch
‘>’ als Programmzeile gekennzeichnet
literat . . . ‘wörtlich’
fak :: Int -> Int
fak n = if n == 0 then 1 else n * fak (n - 1)
D. Rösner PGP 2011 . . .
26
D. Rösner PGP 2011 . . .
27
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Einführung
Beispiel eines literaten Skripts
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Haskell – lexikalische Konventionen
Die Berechnung der Funktion Fakultät ist ein
Standardbeispiel fuer Rekursion.
Identifikatoren: Bezeichner von Variablen, von Typen von
Funktionen usw.
> fak :: Int -> Int
> fak n = if n == 0 then 1 else n * fak (n - 1)
Identifikatoren müssen in Haskell mit einem Buchstaben
beginnen
Eine Variante mit Pattern-Matching:
dieser kann von einer beliebigen Sequenz von
Buchstaben, Ziffern, Unterstrichen (_) und einzelnen
Anführungszeichen (’) gefolgt sein
> fak 0 = 1
> fak n = n * fak (n - 1)
D. Rösner PGP 2011 . . .
Einführung
28
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Einführung
Haskell – lexikalische Konventionen
30
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Haskell – lexikalische Konventionen
Konventionen für führende Großbuchstaben bzw.
Kleinbuchstaben
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|_
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 2011 . . .
D. Rösner PGP 2011 . . .
31
D. Rösner PGP 2011 . . .
32
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Einführung
Haskell – lexikalische Konventionen
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Funktionen in Prelude.hs
Empfehlung: mnemonische, ’sprechende’ Namen
verwenden
z.B.
Prelude.hs enthält viele nützliche Funktionen
zinssatz
statt nur z
/usr/local/hugs98-Dec2001/share/hugs/lib/Prelude.hs
Empfehlung: bei Namen, die aus mehreren Worten
zusammengesetzt sind, den Beginn des zweiten Worts
(und ggf. folgender Wörter) in Großbuchstaben schreiben
z.B. letztesElement
D. Rösner PGP 2011 . . .
Einführung
D. Rösner PGP 2011 . . .
33
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Einführung
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 2011 . . .
35
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Listenfunktionen cont.
36
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 2011 . . .
37
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Einführung
Listenfunktionen cont.
Funktionen in Prelude.hs
concat
concat
:: [[a]] -> [a]
= foldr (++) []
length
length
:: [a] -> Int
= foldl’ (\n _ -> n + 1) 0
(!!)
(x:_)
(_:xs)
(_:_)
[]
Funktionen, die ein Paar als Argument nehmen, vs.
Funktionen mit zwei Argumenten
:: [a] -> Int -> a
0
= x
n | n>0 = xs !! (n-1)
_
= error "Prelude.!!: negative index"
_
= error "Prelude.!!: index too large"
!!
!!
!!
!!
D. Rösner PGP 2011 . . .
Einführung
x
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 2011 . . .
38
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Einführung
Funktionen in Prelude.hs cont.
id
id
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Funktionen in Prelude.hs: Faltung
:: a -> a
= x
foldl
:: (a -> b -> a) -> a -> [b] -> a
foldl f z []
= z
foldl f z (x:xs) = foldl f (f z x) xs
const
const k _
:: a -> b -> a
= k
(.)
(f . g) x
:: (b -> c) -> (a -> b) -> (a -> c)
= f (g x)
foldr
:: (a -> b -> b) -> b -> [a] -> b
foldr f z []
= z
foldr f z (x:xs) = f x (foldr f z xs)
flip
flip f x y
:: (a -> b -> c) -> b -> a -> c
= f y x
...
D. Rösner PGP 2011 . . .
39
40
D. Rösner PGP 2011 . . .
41
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Einführung
Funktionen in Prelude.hs
Literatur: I
Richard Bird.
Introduction to functional programming using Haskell.
Prentice Hall Europe, 2000.
ISBN 0-13-484346-0; 2nd edition.
Fehlererzeugung:
primitive error
:: String -> a
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.
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 2011 . . .
Einführung
Einleitung
Sprachelemente
Skripte
Lexik
Prelude
Graham Hutton.
Programming in Haskell.
Cambridge University Press, 2006.
ISBN 0521692695.
42
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.
D. Rösner PGP 2011 . . .
44
D. Rösner PGP 2011 . . .
43
Herunterladen