Geben Sie für folgende Haskell-Ausdrücke jeweils an, ob sie korrekt sind, sowie ggf. einen zugehörigen Typen:
1.1
(1.1)
(1,1)
true
'string'
"c"
['1', '2', '3', '4']
Geben Sie für folgende Haskell-Ausdrücke jeweils an, ob sie korrekt sind, sowie ggf. einen zugehörigen Typen:
1.1
(1.1)
(1,1)
true
'string'
"c"
['1', '2', '3', '4']
Angabe des Typs erfolgt nach
::.
1.1 :: Float oder 1.1 :: Double (1.1) :: Float oder Double, ist genau das gleiche (1,1) :: (Int, Int) ist Tupel, da Komma! true nicht typkorrekt, da kleingeschrieben 'string' nicht typkorrekt, da einfache Hochkommata "c" :: String ['1', '2', '3', '4'] :: String oder ['1', '2', '3', '4'] :: [Char]
Geben Sie für folgende Haskell-Ausdrücke jeweils an, ob sie korrekt sind, sowie den allgemeinsten Typ:
1.1
(1.1) s.o.
(1,1)
true True
'string' 's'
"c"
['1', '2', '3', '4']
1.1 :: (Fractional a) => a (1,1) :: (Num a,Num b) => (a,b)2 Typvariablen, da z.B. Int+Float True :: Bool 's' :: Char "c" :: String ['1', '2', '3', '4'] :: String
Bestimmen Sie jeweils den allgemeinsten Typ der folgenden Haskell-Funktionen:
not
(<)
(>=)
(^)
(**)
not :: Bool -> Bool (<) :: Ord a => a -> a -> Bool (>=) :: Ord a => a -> a -> Bool Ord impliziert bereits Eq (^) :: (Num a, Integral b) => a -> b -> a (**) :: Fractional a => a -> a -> a
Bestimmen Sie jeweils den allgemeinsten Typ der folgenden Haskell-Ausdrücke:
(+1)
(/0)
((^) 3)
(^3)
2^3
(+1) :: (Num a) => a -> a (/0) :: (Fractional a) => a -> a syntaktisch korrekt ((^) 3) :: (Integral a, Num b) => a -> b (^)::(Integral b, Num a) => a -> b -> a (^3) :: (Num a) => a -> a 2^3 :: (Num a) => a
Erzeugen Sie mittels Listenkomprehension folgende Listen:
[n^4-2*n | n <- [2,4..]] [n | n <- [1..], n `mod` 11 == 3, n `mod` 13 == 7] [(n, (p, (n-p))) | n <- [1..], p <- [1..(n `div` 2)], not(isPrime n), isPrime p, isPrime (n-p)]
[1.0,1.3,1.7,2.0,2.3,2.7,...]
[z+d | z <- [1..], d <- [0,0.3,0.7]] [x+y+z | x <- [0,0.01,0.02,0.05,0.10,0.20,0.50,1.00,2.00], y <- [0,0.01,0.02,0.05,0.10,0.20,0.50,1.00,2.00], z <- [0.01,0.02,0.05,0.10,0.20,0.50,1.00,2.00], (x == 0 && y == 0) || (x < y && y < z)]
Klausuraufgabe SS11-2
Bestimmen Sie jeweils den Typ der folgenden Haskell-Ausdrücke:
('1', '2':"3", 4 < 5) :: (Char, String, Bool) [(last, tail), (head, take 5)] :: [ ([a] -> a, [b] -> [b]) ] [(+), (-)] :: Num a => [a -> a -> a] [map (const True), map not] :: [ [Bool] -> [Bool] ]
Klausuraufgabe SS12-2 und SS12-1
Gegeben seien die folgenden Funktionsdefinitionen. Bestimmen Sie jeweils den allgemeinsten Typ der Funktionen:
f :: (Eq a) => a -> [[a]] -> Bool f x y = any (==x) (concat y) g :: (Num a, Enum a) => a -> a -> [a] g u v = map (\(x,y) -> x * y) (zip [u..v] [u..v]) h :: (Ord a) => a -> Maybe a -> Bool h x (Just y) = x < y h x (Nothing) = False
Definieren Sie folgende Funktionen. Verwenden Sie wenn nötig explizite Rekursion.
addPair (a,b) (c,d) = (a+c, b+d)
map f (x:xs) = f x : map f xs map _ [] = []
zip (x:xs) (y:ys) = (x,y) : zip xs ys zip _ _ = []
unzip ((x,y):ls) = (x:xs, y:ys) where (xs, ys) = unzip ls unzip [] = ([],[])
addPairs [] = (0,0) addPairs ((a,b):xs) = (a+c, b+d) where (c,d) = addPairs xs
zipWith f (x:xs) (y:ys) = (f x y) : zipWith f xs ys zipWith _ _ _ = []
concat [] = [] concat (x:xs) = x ++ concat xs
splitAt n xs = (take n xs, drop n xs) splitAt' 0 xs = ([], xs) splitAt' _ [] = ([], []) splitAt' n (x:xs) = (x:as, bs) where (as,bs) = splitAt' (n-1) xs
Definieren Sie folgende Funktionen mit Hilfe von foldl oder foldr:
length = foldr (\x y -> 1+y) 0 length' = foldl (\x y -> x+1) 0
quadratsumme n = foldr (\x y -> x^2 + y) 0 [1..n] quadratsumme' n = foldl (\x y -> x + y^2) 0 [1..n]
reverse = foldr (\x y -> y++[x]) [] reverse' = foldl (\x y -> [y]++x) []
fak n = foldr (*) 1 [1..n]
Bei der Huffman-Codierung handelt es sich um ein einfaches Datenkompressionsverfahren. Hierbei werden Buchstaben anhand ihrer Häufigkeiten in einem Binärbaum abgespeichert, in dessen Blätter jeweils ein Buchstabe und seine Häufigkeit gespeichert wird.
/\ Node ___________/ \________ /\ /\ Node / \ ______/ \_____ / \ /\ \ Node / Char 651 'a' / \ \ / / Char 435 'u' \ Char 615 't' / Char 978 'n' Char 253 'm'
Definiere einen Datentyp für diesen Huffman-Tree und gib die Beispielinstanz an!
type Quantity = Integer data HuffmanTree = Node HuffmanTree HuffmanTree | Char Quantity Char deriving (Eq, Ord, Show) bsp = Node (Node (Char 615 ’t’) (Char 651 ’a’)) (Node (Node (Char 253 ’m’) (Char 435 ’u’)) (Char 978 ’n’) )
Schreibe Funktion quantitySum :: HuffmanTree -> Integer
als Instanz von foldHuffmanTree
, welche die Summe aller im übergebenen Huffman-Tree gespeicherten Quantity-Werte zurückliefert.
quantitySum :: HuffmanTree -> Integer
quantitySum = foldHuffmanTree const (+)
Definiere eine nicht-rekursive Funktion chars :: HuffmanTree -> [(Char,Quantity)]
, die eine Liste aller im übergebenen Huffman-Tree gespeicherten Buchstaben sowie ihrer absoluten Häufigkeiten zurückliefert. Die Reihenfolge ist dabei beliebig.
chars :: HuffmanTree -> [(Char,Quantity)]
chars = foldHuffmanTree (\q c -> [(c,q)]) (++)
fold
auf rekursiven DatentypenGegeben sei der folgende Datentyp MathExpr
, mit dem einfache mathematische Terme beschrieben werden können:
type Value = Int data MathExpr = Value Value | Plus MathExpr MathExpr | Mal MathExpr MathExpr | Fakultaet MathExpr
Geben Sie den Term (3+4)*7!
als Instanz dieses Typs an!
bsp = Mal (Plus (Value 3) (Value 4)) (Fakultaet (Value 7))
type Value = Int data MathExpr = Value Value | Plus MathExpr MathExpr | Mal MathExpr MathExpr | Fakultaet MathExpr
Definieren Sie rekursiv eine Funktion calcRec :: MathExpr -> Value
, die den Term evaluiert, also den berechneten Wert zurückliefert.
calcRec :: MathExpr -> Value calcRec (Value v) = v calcRec (Plus a b) = (calcRec a) + (calcRec b) calcRec (Mal a b) = (calcRec a) * (calcRec b) calcRec (Fakultaet n) = fak m where m = calcRec n fak 0 = 1 fak n = n * fak (n-1)
type Value = Int data MathExpr = Value Value | Plus MathExpr MathExpr | Mal MathExpr MathExpr | Fakultaet MathExpr
Definieren Sie die fold
-Funktion foldME
!
foldME :: (Value -> a) -> (a -> a -> a) -> (a -> a -> a) -> (a -> a) -> MathExpr -> a foldME vf pf mf ff = m where m (Value v) = vf v m (Plus p q) = pf (m p) (m q) m (Mal p q) = mf (m p) (m q) m (Fakultaet n) = ff (m n)
foldME :: (Value -> a) -> (a -> a -> a) -> (a -> a -> a) -> (a -> a) -> MathExpr -> a foldME vf pf mf ff = m where m (Value v) = vf v m (Plus p q) = pf (m p) (m q) m (Mal p q) = mf (m p) (m q) m (Fakultaet n) = ff (m n)
Definieren Sie die Function values :: MathExpr -> [Value]
als Instanz von foldME
, welches eine
Liste aller im Termbaum enthaltenen Werte (Value
's) zurückliefert. Die Reihenfolge ist unerheblich.
values :: MathExpr -> [Value] values = foldME (\v -> [v]) (++) (++) id
foldME :: (Value -> a) -> (a -> a -> a) -> (a -> a -> a) -> (a -> a) -> MathExpr -> a foldME vf pf mf ff = m where m (Value v) = vf v m (Plus p q) = pf (m p) (m q) m (Mal p q) = mf (m p) (m q) m (Fakultaet n) = ff (m n)
Definieren Sie die nicht-rekursive Function calc :: MathExpr -> Value
, die den Wert des übergebenen Terms berechnet.
calc :: MathExpr -> Value calc = foldME id (+) (*) fak where fak 0 = 1 fak n = n * fak (n-1)
... zum Repetitorium gibt's hier:
fnogatz.github.io/talks/pdp-rep-14/haskell/
Thanks to Benjamin Erb for the html5slides and uulm template.
Title image: Miran Lipovača under CC BY-NC-SA 3.0