Programmieren in Haskell Programmieren mit Listen Peter Steffen Universit¨ at Bielefeld Technische Fakult¨ at

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¨ unscht ist eine Funktion sortList :: Ord a => List a -> List a, so daß f¨ ur 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¨ugen

isortList :: Ord a => List a -> List a isortList Nil = Nil isortList (Cons x xs) = insertList x (isortList xs) where insertList insertList | 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¨ugen

isortList :: Ord a => List a -> List a isortList Nil = Nil isortList (Cons x xs) = insertList x (isortList xs) where insertList insertList | 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¨ange, 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¨ange, 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¨ange, 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¨ahlungen 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¨ahlungen 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¨at 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¨at 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¨at 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