Gruppen 5 und 7
Samuel Teuber
propa@teuber.dev
https://teuber.dev/propa
Wenn es sich irgend vermeiden lässt: Bitte keine handschriftlichen Code-Abgaben
Haskell ist anders, aber lasst euch davon nicht verwirren!
Mergesort, Horner-Schema: Nutzt die Algorithmen, die angegeben sind!
Zwei Optimierungsmöglichkeiten:
f (x:xs) True = [x]
f l False = l
...oder...
f l@(x:xs) a
| a = [x]
| otherwise = l
f l@(x:xs) a
| a = [x]
| otherwise = l
f [1,2,3] True
f [1,2,3] False
Currying!
cmult p n = map (*n) p
Wie können wir folgende Ausdrücke eleganter schreiben:
take 10 (iterate (+1) 0)
take 10 (iterate (+2) 0)
takeWhile (<=10) (iterate (+2) 0)
take 10 [0..]
take 10 [0,2..]
[0,2..10]
a -> a
\x -> x
(a -> b) -> a -> b
\x -> x
(a -> b) -> (a -> b)
\x -> x
a -> b -> a
\x y -> x
Alle wohldefinierten, semantisch unterschiedlichen Funktionen des Typs
a -> a -> a
\x y -> x
\x y -> y
Leere Liste vom Typ [a]
[]
Einelementige Liste vom Typ [Int]
[42]
Leere Liste vom Typ [[a]]
[]
Liste vom Typ [[a]]
, die nur die leere Liste enthält.
[[]]
Warum gibt es keinen Wert, der für alle Typen a
eine einelementige Liste von Typ [a]
darstellt?
Enthaltener Wert? Es gibt kein null
in Haskell
Gibt es einen Wert, der für alle Typen a
eine einelementige Liste vom Type [[a]]
darstellt?
Ja, nämlich:
[[]]
Geben Sie den Wert von [[[[[[[[[[[a]]]]]]]]]]]
mit der kürzesten Schreibweise an
[]
type Polynom = [Double]
cmult :: Polynom -> Double -> Polynom
cmult p c = map (*c) p
eval :: Polynom -> Double -> Double
eval p x = foldr (\a v -> a + v*x) 0 p
deriv :: Polynom -> Polynom
deriv [] = []
deriv p =zipWith (*) [1..] (tail p)
...schon wieder...
Beispiel: Listen-Typ
[t]
ist der Typ von Listen mit Elementen vom Typ t
t
beliebigSichtweisen:
[ ]
erzeugen neue Typen aus bestehendenVergleichbares in Java: Generics
LinkedList<T>
... sind polymorph, denn...
s -> t
... beschreibt den Typ aller Funktionen von s
nach t
(s
,t
beliebig)
...sind polymorph, denn...
(,) :: s -> t -> (s,t)
...und umgekehrt...
fst :: (s,t) -> s
snd :: (s,t) -> t
...kennen wir auch schon...
foldr :: (a -> b -> b) -> b -> [a] -> b
Definiere rand :: [Integer]
mit
$$
m = 2^{16},
a = 25173,
b = 13849,
x_0 = 32
$$
-- Übungsaufgabe 3
a = 25173
b = 13849
rand = iterate (\x -> (a*x + b) `mod` (2^16)) 32
rand' = 32 : map (\x -> (a*x + b) `mod` (2^16)) rand'
take 10 rand
take 10 rand'
Wir nutzen rand
weiter
Prozedur für fairen Münzwurf von Neumann:
-- Übungsaufgabe 4
neumann :: [Bool]
unfairCoin = (map (\x -> x < 2^15) rand)
neumann = neumannHelper unfairCoin
where neumannHelper (x:y:xs)
| x==y = neumannHelper xs
| otherwise = x : neumannHelper xs
take 10 neumann
Wir zählen die Menge an Köpfen und Zahlen in den ersten $n$ Münzwürfen...
-- Übungsaufgabe 5
coinRatio :: Int -> Double
coinRatio n = count / ((fromIntegral n) - count)
where count = fromIntegral (length (filter id (take n neumann)))
coinRatio 1000000
:t (/)
:t div
splitWhen p [] = ([],[])
splitWhen p l@(x:xs)
| p x = ([],l)
| otherwise = let (l1, l2) = splitWhen p xs in (x:l1, l2)
input = "aaaaaaabbbbbbccceeeedaaaaaabbbe"
splitWhen (/='a') input
runlength :: String -> [(Char, Int)]
runlength [] = []
runlength l@(x:xs) = (x, length a) : (runlength b)
where
(a,b) = splitWhen (/=x) l
asdf x
|x = 1
| otherwise = 2
runlength input
repeat' (c,0) = []
repeat' (c,n) = c : repeat' (c, (n-1))
repeat' ('a',4)
decode [] = ""
decode (x:xs) = (repeat' x) ++ (decode xs)
decode (runlength input)