Programmieren in Haskell

Werbung
Programmieren in Haskell
Programmieren mit Listen II
Programmieren in Haskell
1
Was wir heute machen
• Von eigenen Listen zu eingebauten
• Eine Sortierfunktion
• Nützliche Listenfunktionen
• Listenzucker und Listenbeschreibungen
• Primzahlen
• Noch ’ne Sortierfunktion
• n-Damen-Problem
• Semantik von Listenbeschreibungen
Programmieren in Haskell
2
Von eigenen Listen zu eingebauten
data List a = Nil | Cons a (List a)
data [a] = [] | (a:[a])
Programmieren in Haskell
-- Pseudocode
3
Von eigenen Listen zu eingebauten
data List a = Nil | Cons a (List a)
data [a] = [] | (a:[a])
-- Pseudocode
Nil :: List a
Cons 1 (Cons 2 (Cons 3 Nil)) :: Num a => List a
Cons "hallo" (Cons "welt" Nil) :: List [Char]
[] :: [a]
1:2:3:[] :: Num a => [a]
"hallo":"welt":[] :: [[Char]]
Programmieren in Haskell
-- "normale" infix-Schreibweise
-- ebenso
3
Von eigenen Listen zu eingebauten
data List a = Nil | Cons a (List a)
data [a] = [] | (a:[a])
-- Pseudocode
Nil :: List a
Cons 1 (Cons 2 (Cons 3 Nil)) :: Num a => List a
Cons "hallo" (Cons "welt" Nil) :: List [Char]
[] :: [a]
1:2:3:[] :: Num a => [a]
"hallo":"welt":[] :: [[Char]]
-- "normale" infix-Schreibweise
-- ebenso
(:) 1 ((:) 2 ((:) 3 [])) :: Num a => [a]
Programmieren in Haskell
-- prefix-Schreibweise!
3
Sortieren durch Einfügen
isort :: Ord a => [a] -> [a]
isort [] = []
isort (x:xs) = insert x (isort xs) where
insert x [] = [x]
insert x (y:ys)
| x <= y = x:y:ys
| x > y = y:(insert x ys)
Programmieren in Haskell
4
Nützliche Listenfunktionen
head’ :: [a] -> a
head’ [] = error "head’ not defined for empty lists"
head’ (x:xs) = x
tail’ :: [a] -> [a]
tail’ [] = error "tail’ not defined for empty lists"
tail’ (x:xs) = xs
Programmieren in Haskell
5
length’ :: Num a => [b] -> a
length’ []
= 0
length’ (x:xs) = 1 + length’ xs
sum’ :: Num a => [a] -> a
sum’ []
= 0
sum’ (x:xs) = x + sum’ xs
product’ :: Num a => [a] -> a
product’ []
= 1
product’ (x:xs) = x * product’ xs
Programmieren in Haskell
6
enumFromTo’ :: (Enum a, Ord a) => a -> a -> [a]
enumFromTo’ a b
| a > b = []
| a == b = [a]
| a < b = a:(enumFromTo’ (succ a) b)
factorial’ :: Integral a => a -> a
factorial’ n
| n < 0 = error "factorial’ not defined for negative values"
| otherwise = product’ (enumFromTo’ 1 n)
Programmieren in Haskell
7
append’ :: [a] -> [a] -> [a]
append’ []
ys = ys
append’ (x:xs) ys = x:(append’ xs ys)
reverse’Slow :: [a] -> [a]
reverse’Slow [] = []
reverse’Slow (x:xs) = append’ (reverse’Slow xs) [x]
oder:
reverse’Slow (x:xs) = reverse’Slow xs ++ [x]
Programmieren in Haskell
8
take’
take’
| n
take’
take’
| n
| n
:: Integral a => a -> [b] -> [b]
n xs
< 0 = error "take’ not defined for negative values"
n [] = []
n (x:xs)
== 0 = []
> 0 = x:(take’ (n-1) xs)
Programmieren in Haskell
9
drop’
drop’
| n
drop’
drop’
| n
| n
:: Integral a => a -> [b] -> [b]
n xs
< 0 = error "drop’ not defined for negative values"
n [] = []
n (x:xs)
== 0 = x:xs
> 0 = drop’ (n-1) xs
Programmieren in Haskell
10
map’ :: (a -> b) -> [a] -> [b]
map’ f [] = []
map’ f (x:xs) = (f x):(map’ f xs)
filter’ :: (a -> Bool) -> [a] -> [a]
filter’ p [] = []
filter’ p (x:xs)
| p x
= x:filter’ p xs
| otherwise =
filter’ p xs
Programmieren in Haskell
11
concat’ :: [[a]] -> [a]
concat’ [] = []
concat’ (xs:xss) = append’ xs (concat’ xss)
Programmieren in Haskell
12
Listen-Zucker
[1 ..] Liste der positiven, ganzen Zahlen
[1 .. 99] Liste der positiven, ganzen Zahlen bis einschließlich 99
[1, 3 ..] Liste der ungeraden, positiven Zahlen
[1, 3 .. 99] Liste der ungeraden, positiven Zahlen bis einschließlich 99
Programmieren in Haskell
13
Listenbeschreibungen
squares = [n*n | n <- [0..99]]
map f xs = [f a | a <- xs]
a ‘elem‘ xs = or [a == b | b <- xs]
Programmieren in Haskell
14
Primzahlen
primesSlow :: Integral a => [a]
primesSlow = [n | n <- [2..], divisors n == [1,n]] where
divisors :: Integral a => a -> [a]
divisors n = [d | d <- [1..n], n ‘mod‘ d == 0]
Programmieren in Haskell
15
Sieb des Eratosthenes
primes :: Integral a => [a]
primes = sieve [2..] where
sieve :: Integral a => [a] -> [a]
sieve (a:xs) = a:sieve [n | n <- xs, n ‘mod‘ a /= 0]
Programmieren in Haskell
16
Quicksort
qsort :: Ord a => [a] -> [a]
qsort [] = []
qsort (a:xs) = qsort [b | b <- xs, b < a] ++
[a] ++
qsort [b | b <- xs, b >= a]
Programmieren in Haskell
17
n-Damen-Problem
type Board = [Integer]
queens :: Integer -> [Board]
queens n = place 1 [1..n] [] []
Programmieren in Haskell
18
place :: Integer -> [Integer] -> [Integer] -> [Integer] -> [Board]
place c [] ud dd = [[]]
place c rs ud dd = [q:qs | q <- rs,
let uq = q - c,
let dq = q + c,
uq ‘notElem‘ ud,
dq ‘notElem‘ dd,
qs <- place (c+1) (delete q rs) (uq:ud) (dq:dd)]
delete q (x:xs) | q == x
= xs
| otherwise = x:delete q xs
Programmieren in Haskell
19
Semantik von Listenbeschreibungen
Programmieren in Haskell
[ e | p <- l ]
=
map (\p -> e) l
[ e | b ]
=
if b then [e] else []
[ e | let ds ]
=
let ds in [e]
[ e | q1 , q2 ]
=
concat [ [ e | q2 ] | q1 ]
20
Herunterladen