Programmieren in Haskell Programmieren mit Listen

Werbung
Programmieren in Haskell
Programmieren mit Listen
Peter Steffen
Universität Bielefeld
Technische Fakultät
14.11.2008
1
Programmieren in Haskell
Ein eigener Listen-Datentyp
data List a = Nil | Cons a (List a) deriving (Show,Eq)
Listen sind dann zum Beispiel:
Nil :: List a
Cons 1 (Cons 2 (Cons 3 Nil)) :: Num a => List a
Cons "hallo" (Cons "welt" Nil) :: List [Char]
2
Programmieren in Haskell
Spezifikation des Sortierproblems
Gewünscht ist eine Funktion
sortList :: Ord a => List a -> List a, so daß für jede Liste
xs :: List a (mit Ord a), die Elemente von sortList xs geordnet
sind, keine Elemente hinzukommen und keine verlorengehen.
3
Programmieren in Haskell
Sortieren durch Einfügen
isortList :: Ord a => List a -> List a
isortList Nil = Nil
isortList (Cons x xs) = insertList x (isortList xs) where
insertList
insertList
| x <= y
| x > y
x
x
=
=
Nil = Cons x Nil
(Cons y ys)
Cons x (Cons y ys)
Cons y (insertList x ys)
Beispiel:
sortList (Cons 1 (Cons 4 (Cons 2 Nil)))
=> Cons 1 (Cons 2 (Cons 4 Nil))
4
Programmieren in Haskell
Sortieren durch Einfügen
isortList :: Ord a => List a -> List a
isortList Nil = Nil
isortList (Cons x xs) = insertList x (isortList xs) where
insertList
insertList
| x <= y
| x > y
x
x
=
=
Nil = Cons x Nil
(Cons y ys)
Cons x (Cons y ys)
Cons y (insertList x ys)
Beispiel:
sortList (Cons 1 (Cons 4 (Cons 2 Nil)))
=> Cons 1 (Cons 2 (Cons 4 Nil))
4
Programmieren in Haskell
Kopf und Restliste
headList :: List a -> a
headList Nil = error "headList not defined for empty lists"
headList (Cons x xs) = x
tailList :: List a -> List a
tailList Nil = error "tailList not defined for empty lists"
tailList (Cons x xs) = xs
5
Programmieren in Haskell
Länge, Summe und Produkt
lengthList :: Num a => List b -> a
lengthList Nil
= 0
lengthList (Cons x xs) = 1 + lengthList xs
sumList :: Num a => List a -> a
sumList Nil
= 0
sumList (Cons x xs) = x + sumList xs
productList :: Num a => List a -> a
productList Nil
= 1
productList (Cons x xs) = x * productList xs
6
Programmieren in Haskell
Länge, Summe und Produkt
lengthList :: Num a => List b -> a
lengthList Nil
= 0
lengthList (Cons x xs) = 1 + lengthList xs
sumList :: Num a => List a -> a
sumList Nil
= 0
sumList (Cons x xs) = x + sumList xs
productList :: Num a => List a -> a
productList Nil
= 1
productList (Cons x xs) = x * productList xs
6
Programmieren in Haskell
Länge, Summe und Produkt
lengthList :: Num a => List b -> a
lengthList Nil
= 0
lengthList (Cons x xs) = 1 + lengthList xs
sumList :: Num a => List a -> a
sumList Nil
= 0
sumList (Cons x xs) = x + sumList xs
productList :: Num a => List a -> a
productList Nil
= 1
productList (Cons x xs) = x * productList xs
6
Programmieren in Haskell
Aufzählungen
enumFromToList :: (Enum a, Ord a) => a -> a -> List a
enumFromToList a b
| a > b = Nil
| a == b = Cons a Nil
| a < b = Cons a (enumFromToList (succ a) b)
Beispiele:
enumFromToList 1 5
=> Cons 1 (Cons 2 (Cons 3 (Cons 4 (Cons 5 Nil))))
enumFromToList 5 4
=> Nil
enumFromToList ’a’ ’d’
=> Cons ’a’ (Cons ’b’ (Cons ’c’ (Cons ’d’ Nil)))
7
Programmieren in Haskell
Aufzählungen
enumFromToList :: (Enum a, Ord a) => a -> a -> List a
enumFromToList a b
| a > b = Nil
| a == b = Cons a Nil
| a < b = Cons a (enumFromToList (succ a) b)
Beispiele:
enumFromToList 1 5
=> Cons 1 (Cons 2 (Cons 3 (Cons 4 (Cons 5 Nil))))
enumFromToList 5 4
=> Nil
enumFromToList ’a’ ’d’
=> Cons ’a’ (Cons ’b’ (Cons ’c’ (Cons ’d’ Nil)))
7
Programmieren in Haskell
Fakultät
factorialList :: Integral a => a -> a
factorialList n
| n < 0 = error "factorialList not defined for negative values"
| otherwise = productList (enumFromToList 1 n)
Beispiele: factorialList 4 => 24, factorialList 0 => 1
Alternative Definition ohne Listen:
factorial ::
factorial n
| n < 0 =
| n == 0 =
| n > 0 =
8
Integral a => a -> a
error "factorial not defined for negative values"
1
n * factorial (n-1)
Programmieren in Haskell
Fakultät
factorialList :: Integral a => a -> a
factorialList n
| n < 0 = error "factorialList not defined for negative values"
| otherwise = productList (enumFromToList 1 n)
Beispiele: factorialList 4 => 24, factorialList 0 => 1
Alternative Definition ohne Listen:
factorial ::
factorial n
| n < 0 =
| n == 0 =
| n > 0 =
8
Integral a => a -> a
error "factorial not defined for negative values"
1
n * factorial (n-1)
Programmieren in Haskell
Fakultät
factorialList :: Integral a => a -> a
factorialList n
| n < 0 = error "factorialList not defined for negative values"
| otherwise = productList (enumFromToList 1 n)
Beispiele: factorialList 4 => 24, factorialList 0 => 1
Alternative Definition ohne Listen:
factorial ::
factorial n
| n < 0 =
| n == 0 =
| n > 0 =
8
Integral a => a -> a
error "factorial not defined for negative values"
1
n * factorial (n-1)
Programmieren in Haskell
Append
appendList :: List a -> List a -> List a
appendList Nil
ys = ys
appendList (Cons x xs) ys = Cons x (appendList xs ys)
Beispiel:
appendList (enumFromToList 1 5) (enumFromToList 6 10)
== enumFromToList 1 10
=> True
9
Programmieren in Haskell
Append
appendList :: List a -> List a -> List a
appendList Nil
ys = ys
appendList (Cons x xs) ys = Cons x (appendList xs ys)
Beispiel:
appendList (enumFromToList 1 5) (enumFromToList 6 10)
== enumFromToList 1 10
=> True
9
Programmieren in Haskell
Reverse
reverseListSlow :: List a -> List a
reverseListSlow Nil = Nil
reverseListSlow (Cons x xs) =
appendList (reverseListSlow xs) (Cons x Nil)
Beispiel:
reverseListSlow (enumFromToList 1 3)
=> Cons 3 (Cons 2 (Cons 1 Nil))
10
Programmieren in Haskell
Reverse
reverseListSlow :: List a -> List a
reverseListSlow Nil = Nil
reverseListSlow (Cons x xs) =
appendList (reverseListSlow xs) (Cons x Nil)
Beispiel:
reverseListSlow (enumFromToList 1 3)
=> Cons 3 (Cons 2 (Cons 1 Nil))
10
Programmieren in Haskell
Take
takeList
takeList
| n <
takeList
takeList
| n ==
| n >
11
:: Integral a => a -> List b -> List b
n xs
0 = error "takeList not defined for negative values"
n Nil = Nil
n (Cons x xs)
0 = Nil
0 = Cons x (takeList (n-1) xs)
Programmieren in Haskell
Beispiele:
takeList 3 (enumFromToList 1 10)
=> Cons 1 (Cons 2 (Cons 3 Nil))
takeList 3 (enumFromToList 1 2)
=> Cons 1 (Cons 2 Nil)
takeList 0 (enumFromToList 1 10)
=> Nil
takeList (-5) (enumFromToList 1 10)
=> Program error: takeList not defined for negative values
12
Programmieren in Haskell
Drop
dropList
dropList
| n <
dropList
dropList
| n ==
| n >
:: Integral a => a -> List b -> List b
n xs
0 = error "dropList not defined for negative values"
n Nil = Nil
n (Cons x xs)
0 = (Cons x xs)
0 = dropList (n-1) xs
Beispiele:
dropList 3 (enumFromToList 1 10)
=> Cons 4 (Cons 5 (Cons 6 (Cons 7 (Cons 8 (Cons 9 (Cons 10 Nil))))))
dropList 10 (enumFromToList 1 5)
=> Nil
13
Programmieren in Haskell
Drop
dropList
dropList
| n <
dropList
dropList
| n ==
| n >
:: Integral a => a -> List b -> List b
n xs
0 = error "dropList not defined for negative values"
n Nil = Nil
n (Cons x xs)
0 = (Cons x xs)
0 = dropList (n-1) xs
Beispiele:
dropList 3 (enumFromToList 1 10)
=> Cons 4 (Cons 5 (Cons 6 (Cons 7 (Cons 8 (Cons 9 (Cons 10 Nil))))))
dropList 10 (enumFromToList 1 5)
=> Nil
13
Programmieren in Haskell
Map
mapList :: (a -> b) -> List a -> List b
mapList f Nil = Nil
mapList f (Cons x xs) = Cons (f x) (mapList f xs)
Beispiel:
mapList (+1) (enumFromToList 1 4)
Cons 2 (Cons 3 (Cons 4 (Cons 5 Nil)))
14
Programmieren in Haskell
Map
mapList :: (a -> b) -> List a -> List b
mapList f Nil = Nil
mapList f (Cons x xs) = Cons (f x) (mapList f xs)
Beispiel:
mapList (+1) (enumFromToList 1 4)
Cons 2 (Cons 3 (Cons 4 (Cons 5 Nil)))
14
Programmieren in Haskell
Filter
filterList :: (a -> Bool) -> List a -> List a
filterList p Nil = Nil
filterList p (Cons x xs)
| p x
= Cons x (filterList p xs)
| otherwise = filterList p xs
Beispiel:
filterList (>5) (enumFromToList 1 10)
=> Cons 6 (Cons 7 (Cons 8 (Cons 9 (Cons 10 Nil))))
15
Programmieren in Haskell
Filter
filterList :: (a -> Bool) -> List a -> List a
filterList p Nil = Nil
filterList p (Cons x xs)
| p x
= Cons x (filterList p xs)
| otherwise = filterList p xs
Beispiel:
filterList (>5) (enumFromToList 1 10)
=> Cons 6 (Cons 7 (Cons 8 (Cons 9 (Cons 10 Nil))))
15
Programmieren in Haskell
Filter-Beispiel
oddList :: Integral a => List a -> List a
oddList = filterList odd where
odd x = x ‘mod‘ 2 /= 0
Beispiel:
oddList (enumFromToList 1 10)
=> Cons 1 (Cons 3 (Cons 5 (Cons 7 (Cons 9 Nil))))
Alternative ohne filterList
oddListBoring
oddListBoring
oddListBoring
| x ‘mod‘ 2
| otherwise
16
:: Integral a => List a -> List a
Nil = Nil
(Cons x xs)
/= 0 = Cons x (oddListBoring xs)
=
oddListBoring xs
Programmieren in Haskell
Filter-Beispiel
oddList :: Integral a => List a -> List a
oddList = filterList odd where
odd x = x ‘mod‘ 2 /= 0
Beispiel:
oddList (enumFromToList 1 10)
=> Cons 1 (Cons 3 (Cons 5 (Cons 7 (Cons 9 Nil))))
Alternative ohne filterList
oddListBoring
oddListBoring
oddListBoring
| x ‘mod‘ 2
| otherwise
16
:: Integral a => List a -> List a
Nil = Nil
(Cons x xs)
/= 0 = Cons x (oddListBoring xs)
=
oddListBoring xs
Programmieren in Haskell
Concat
concatList :: List (List a) -> List a
concatList Nil = Nil
concatList (Cons xs xss) = appendList xs (concatList xss)
Beispiel:
concatList (Cons (enumFromToList 1 3) (Cons (enumFromToList 4 5) Nil
=> Cons 1 (Cons 2 (Cons 3 (Cons 4 (Cons 5 Nil))))
17
Programmieren in Haskell
Concat
concatList :: List (List a) -> List a
concatList Nil = Nil
concatList (Cons xs xss) = appendList xs (concatList xss)
Beispiel:
concatList (Cons (enumFromToList 1 3) (Cons (enumFromToList 4 5) Nil
=> Cons 1 (Cons 2 (Cons 3 (Cons 4 (Cons 5 Nil))))
17
Programmieren in Haskell
Herunterladen