Programmieren in Haskell Syntax und Semantik von Haskell

Werbung
Programmieren in Haskell
Syntax und Semantik von Haskell
Peter Steffen
Universität Bielefeld
Technische Fakultät
13.11.2009
1
Programmieren in Haskell
Was wir heute machen
Datentypdefinitionen
Wertdefinitionen, Variablenbindungen
Musterbindungen
Funktionsbindungen
Bewachte Gleichungen
Lokale Definitionen mit where und let
Gültigkeitsbereiche
Fallunterscheidungen
Syntaktischer Zucker / Kernsprache
2
Programmieren in Haskell
Datentypen, Datentypdefinitionen
3
data Instrument =
|
|
|
Oboe
HonkyTonkPiano
Cello
VoiceAahs
data Musik
Note Ton Dauer
Pause Dauer
Musik :*: Musik
Musik :+: Musik
Instr Instrument Musik
Tempo GanzeZahl Musik
=
|
|
|
|
|
Programmieren in Haskell
Wahrheitswerte
data Bool = False | True
4
-- vordefiniert
Programmieren in Haskell
Ganze Zahlen
data Ganz = Zero |
Succ Ganz
Zero, Succ Zero, Succ (Succ Zero), . . .
Eingebaute Datentypen: Int und Integer
5
Programmieren in Haskell
Tupeltypen
data Pair a b
= Pair a b
data Triple a b c = Triple a b c
Eingebaute Datentypen: (a,b), (a,b,c)
6
Programmieren in Haskell
Listen
data List a = Empty | Front a (List a)
Eingebauter Datentyp: [a]
7
Programmieren in Haskell
Allgemeine Form
data T a1 . . . am
= C1 t11 . . . t1n1
| ...
| Cr tr 1 . . . trnr
T : Typkonstruktor; Ci : (Daten-)Konstruktoren; ai : Typvariablen; tij : Typen
oder Typvariablen
8
Programmieren in Haskell
Allgemeine Form
data T a1 . . . am
= C1 t11 . . . t1n1
| ...
| Cr tr 1 . . . trnr
T : Typkonstruktor; Ci : (Daten-)Konstruktoren; ai : Typvariablen; tij : Typen
oder Typvariablen
8
Programmieren in Haskell
Selektorfunktionen auf Tupeln
9
fst :: (a,b) -> a
fst (a,b) = a
-- vordefiniert
snd :: (a,b) -> b
snd (a,b) = b
-- vordefiniert
Programmieren in Haskell
Selektorfunktionen auf Listen
10
head :: [a] -> a
head (x:xs) = x
-- vordefiniert
tail :: [a] -> [a]
tail (x:xs) = xs
-- vordefiniert
Programmieren in Haskell
Selektorfunktionen auf Musik
ton :: Musik -> Int
ton (Note ton dauer) = ton
dauer :: Musik -> Rational
dauer (Note ton dauer) = dauer
dauer (Pause
dauer) = dauer
11
Programmieren in Haskell
Typsynonyme
12
type GanzeZahl
type Bruch
= Int
= Rational
type Ton
type Dauer
= GanzeZahl
= Bruch
Programmieren in Haskell
Nutzen und Gefahren von Typsynonymen
type OrdList a = [a]
sort :: [a] -> OrdList a
sort xs = xs
Typ ok? Ja
Ergebnis geordnete Liste? Nein (jedenfalls nicht im allgemeinen)
13
Programmieren in Haskell
Nutzen und Gefahren von Typsynonymen
type OrdList a = [a]
sort :: [a] -> OrdList a
sort xs = xs
Typ ok? Ja
Ergebnis geordnete Liste? Nein (jedenfalls nicht im allgemeinen)
13
Programmieren in Haskell
Nutzen und Gefahren von Typsynonymen
type OrdList a = [a]
sort :: [a] -> OrdList a
sort xs = xs
Typ ok? Ja
Ergebnis geordnete Liste? Nein (jedenfalls nicht im allgemeinen)
13
Programmieren in Haskell
Nutzen und Gefahren von Typsynonymen
type OrdList a = [a]
sort :: [a] -> OrdList a
sort xs = xs
Typ ok? Ja
Ergebnis geordnete Liste? Nein (jedenfalls nicht im allgemeinen)
13
Programmieren in Haskell
Nutzen und Gefahren von Typsynonymen
type OrdList a = [a]
sort :: [a] -> OrdList a
sort xs = xs
Typ ok? Ja
Ergebnis geordnete Liste? Nein (jedenfalls nicht im allgemeinen)
13
Programmieren in Haskell
Wertdefinitionen, Variablenbindungen
aShortList :: [Integer]
aShortList = [1,2,3]
helloWorld :: String
helloWorld = "Hello World"
monotonie :: Musik
monotonie = c’ (1/1) :*: monotonie
14
Programmieren in Haskell
Funktionsbindungen
length :: [a] -> Int
length []
= 0
length (a:as) = 1 + length as
15
-- vordefiniert
Programmieren in Haskell
Allgemeiner Fall
f p11 . . . p1n
=
e1
...
=
...
f pk1 . . . pkn
=
ek
pij : Muster, ei : Ausdrücke
16
Programmieren in Haskell
Bewachte Gleichungen
member :: (Ord a) => a -> OrdList a -> Bool
member a []
= False
member a (b:bs) = a >= b && (a == b || member a bs)
member a [] = False
member a (b:bs) = if a < b then False else
if a == b then True else member a bs
member a []
member a (b:bs)
| a < b
| a == b
| a > b
17
= False
= False
= True
= member a bs
Programmieren in Haskell
Lokale Definitionen mit where
sumSquares :: Int -> Int -> Int
sumSquares x y = sqX + sqY where
sqX = x * x
sqY = y * y
18
Programmieren in Haskell
Lokale Definitionen mit let
sumSquares :: Int -> Int -> Int
sumSquares x y = let sqX = x * x
sqY = y * y
in sqX + sqY
19
Programmieren in Haskell
Abseitsregel
Das erste Zeichen der Definition unmittelbar nach dem where
bestimmt die Einrücktiefe des neu eröffneten Definitionsblocks.
Zeilen, die weiter als bis zu dieser Position eingerückt sind, gelten als
Fortsetzungen einer begonnenen lokalen Definition.
Zeilen auf gleicher Einrücktiefe beginnen eine neue Definition im
lokalen Block.
Die erste geringer eingerückte Zeile beendet den lokalen Block.
20
Programmieren in Haskell
Beispiel für Abseitsregel
calc x y = calc1 x +
calc2 y
where
calc1 x = squares x
where
squares x = x * x
calc2 x = x * x * x
21
Programmieren in Haskell
Fallunterscheidungen
length :: [a] -> Int
length []
= 0
length (a:as) = 1 + length as
-- vordefiniert
length’ :: [a] -> Int
length’ as = case as of
[]
-> 0
a:as’ -> 1 + length’ as’
last’ :: [a] -> a
last’ as = case reverse as of
a:as’ -> a
22
Programmieren in Haskell
Funktionsausdrücke
Ist n + 1 ein Wert oder eine Funktion?
Als Funktion:
f n = n + 1
\n -> n + 1
Allgemeine Form eines Funktionsausdrucks:
\p1 . . . pn -> e .
\p1 p2 -> e als Abkürzung für \p1 -> \p2 -> e
23
Programmieren in Haskell
Gestaffelte Funktionen
add :: Integer -> Integer -> Integer
add m n = m + n
add’ :: Integer -> (Integer -> Integer)
add’ = \m -> \n -> m + n
24
Programmieren in Haskell
Gestaffelte Funktionen
note :: Int -> Int -> Dauer -> Musik
note oct h d = Note (12 * oct + h) d
note Eine Note in einer beliebigen Oktave und von beliebiger
Höhe und Dauer.
note 2 Eine Note in der dritten Oktave und von beliebiger Höhe und
Dauer.
note 2 ef Die Note f in der dritten Oktave und von beliebiger Dauer.
note 2 ef (1/4) ergibt Note 29 (1/4).
25
Programmieren in Haskell
Syntaktischer Zucker / Kernsprache
Mustergleichungen / case-Ausdrücke
length []
= 0
length (x:xs) = 1 + length xs
length’ xs = case xs of
[]
-> 0
(x:xs) -> 1 + length’ xs
Funktionsdefinitionen / Funktions-Ausdrücke
add m n = m + n
add’ = \m -> \n -> m + n
26
Programmieren in Haskell
where-Klauseln / let-Ausdrücke
where-Klauseln / let-Ausdrücke
double n = add0 (dup n) where
dup a = (a,a)
double n = let dup a = (a,a) in add0 (dup n)
27
Programmieren in Haskell
Auswertung von Fallunterscheidungen
case C (e1 ) . . . (ek )of{. . . ; C (x1 ) . . . (xk )− > e; . . .}(case-Regel)
⇒ e[x1 /e1 , . . . , xn /en ]
28
Programmieren in Haskell
abs :: (Ord a, Num a) => a -> a
abs n = case n >= 0 of
True -> n
False -> -n
encode :: (Num a) => Maybe a -> a
encode x = case x of
Nothing -> -1
Just n -> abs n
encode (Just 5)
⇒ case Just 5 of {Nothing -> -1; Just n -> abs n} (Def. encode)
29
⇒
abs 5
(case − Regel)
⇒
⇒
case 5 >= 0 of {True -> 5; False -> -5}
case True of {True -> 5; False -> -5}
⇒
5
(Def. abs)
(Def. >=)
(case − Regel)
Programmieren in Haskell
Auswertung von Funktionsanwendungen
(\(x)− > (e))(a) ⇒ e[x/a]
30
(β-Regel)
Programmieren in Haskell
abs
=
encode =
\n -> case n >= 0 of {True -> n; False -> -n}
\x -> case x of {Nothing -> -1; Just n -> abs n}
encode (Just 5)
(Def. encode)
⇒ (\x-> case x of {Nothing-> -1; Just n-> abs n}) (Just 5)
31
⇒
case Just 5 of {Nothing -> -1; Just n -> abs n}
(β − Regel)
⇒
abs 5
⇒
(\n -> case n >= 0 of {True -> n; False -> -n}) 5
⇒
case 5 >= 0 of {True -> 5; False -> -5}
(β − Regel)
⇒
case True of {True -> 5; False -> -5}
(Def. (>=))
⇒
5
(case − Regel)
(Def. abs)
(case − Regel)
Programmieren in Haskell
Auswertung von lokalen Definitionen
let {x1 = e1 ;...;xn = en } in e
⇒ e[x1 /
xn /
32
let {x1 = e1 ;...;xn = en } in e1 , . . . ,(let-Regel)
let {x1 = e1 ;...;xn = en } in en ]
Programmieren in Haskell
rep n a = let x = a:x in take n x
rep 2 8
⇒
let x = 8:x in take 2 x
⇒
take 2 (let x = 8:x in 8:x)
(let − Regel)
⇒
⇒
take 2 (8:let x = 8:x in 8:x)
8:take 1 (let x = 8:x in 8:x)
(let − Regel)
(Def. take)
⇒
(Def. rep)
8:take 1 (8:let x = 8:x in 8:x) (let − Regel)
⇒ 8:8:take 0 (let x = 8:x in 8:x) (Def. take)
⇒
33
8:8:[]
(Def. take)
Programmieren in Haskell
Herunterladen