Beruflich Dokumente
Kultur Dokumente
Haskell Lösungen Rita Loogen Marburg SS15
Haskell Lösungen Rita Loogen Marburg SS15
A1-1
A1-2
-- a)
-- returns k^n
-- takes Num k, Int n >= 0
power :: ( Num a , Integral b ) => a -> b -> a
power k n | n < 0 = error "n has to be >= 0"
| n == 1 =k
| otherwise = k * power k (n-1)
-- b)
-- returns k^n
-- takes Num k, Int n >= 0
poweri :: ( Num a , Integral b ) => a -> b -> a
poweri k n | n < 0 = error "n has to be >= 0"
| n == 1 =k
| n `mod` 2 == 0 = power (power k (n `div` 2)) 2
| otherwise = k * power (power k ((n-1) `div` 2)) 2
A1-3
import Picture
-- a)
picSquare :: Int -> Picture -> Picture
picSquare n p | n == 1 =p
| otherwise = picCol n (picRow n p)
-- b)
dots = ["..",
".."]
-- a)
-- Returns n over k
-- takes n,k >= 0
binom :: Integral a => a -> a -> a
binom n k | k > n =0
| k == 0 =1
| otherwise = (product [(n-k+1)..n]) `div` (product [1..k])
-- b)
-- Returns n over k
-- takes n,k >= 0
binom' :: (Ord a, Num a) => a -> a -> a
binom' n k | k > n =0
| k == 0 || n == k =1
| k == 1 || k == (n-1) = n
| otherwise = (binom' (n-1) (k-1)) +
(binom' (n-1) (k))
A2-2
-- a)
-- b)
grep :: String -> [String] -> [String]
grep xs yss | null xs = []
| otherwise = filter (not . null)
(map (subseqReturn xs) yss)
A3-1
-- a)
-- b)
-- and without
count' :: Char -> String -> Int
count' c cs = length . filter (== c) $ cs
A3-2
-- a)
paarAdd :: Num a => [(a,a)] -> [a]
paarAdd x = [a+b | (a,b) <- x]
-- b)
ordPaare :: Ord a => [(a,a)] -> [(a,a)]
ordPaare x = [(a,b) | (a,b) <- x, a <= b]
-- c)
domino :: Eq a => [(a,a)] -> Bool
domino x = (tail (map fst x)) == (init (map snd x))
-- d)
removeList :: [a] -> [(a,[a])]
removeList x = map (getRmTuppel x) counter
where counter = [0..((length x) -1)]
A3-3
import Formula
-- a)
vars :: Formula -> [String]
vars f = uniq (vars' f)
-- c)
truthTable :: Formula -> [(Assignment,Bool)]
truthTable f = zip (assignments (vars f)) (map (f2b f) (assignments (vars f)))
-- b)
depth :: Tree a -> Int
depth (Node _ Empty Empty) =0
depth (Node _ a Empty) = 1 + depth a
depth (Node _ Empty b) = 1 + depth b
depth (Node _ a b) = 1 + max (depth a) (depth b)
-- c)
depthMin :: Tree a -> Int
depthMin (Node _ Empty Empty) = 0
depthMin (Node _ _ Empty) = 0
depthMin (Node _ Empty _) = 0
depthMin (Node _ a b) = 1 + min (depthMin a) (depthMin b)
-- d)
tree2mtree :: Tree a -> Tree (Maybe a)
tree2mtree (Node x Empty Empty) = Node (Just x) Empty Empty
tree2mtree (Node x Empty b) = Node (Just x) Empty (tree2mtree b)
tree2mtree (Node x a Empty) = Node (Just x) (tree2mtree a) Empty
tree2mtree (Node x a b) = Node (Just x) (tree2mtree a) (tree2mtree b)
-- a)
del :: Eq a => a -> [a] -> [a]
del _ [] = []
del c (x:xs) | x == c = del c xs
| otherwise = x:del c xs
A5-1
import Data.List
import Test.QuickCheck
-- (a)
-- i
prop_LengthInits :: [Int] -> Bool
prop_LengthInits xs = length xs == length (inits xs) - 1
-- ii
prop_LengthInits' :: [Int] -> Bool
prop_LengthInits' xs = and (map (length (inits xs) > )
(map (length ) (inits xs)))
A5-2
data Expr = Var String | Val Int | Add Expr Expr | Mult Expr Expr
deriving Show
-- (a)
simplify :: Expr -> Expr
simplify (Val x) = Val x -- (sim1)
simplify (Var x) = Var x -- (sim2)
simplify (Add e1 e2) = (simplify e1) `add` (simplify e2) -- (sim3)
simplify (Mult e1 e2) = (simplify e1) `mult` (simplify e2) -- (sim4)
-- (b)
size :: Expr -> Int
size (Val _) =1 -- (size1)
size (Var _) =0 -- (size2)
size (Add e1 e2) = size e1 + size e2 -- (size3)
size (Mult e1 e2) = size e1 + size e2 -- (size4)
A5-3
import Data.Char
geheimesWort = ["Verkehrsinfrastrukturfinanzierungsgesellschaft",
"Zwei", "konomie"]
A6-1
A6-2
-- (a)
pairAndSquare :: Num a => [a] -> [(a,a)]
pairAndSquare l = zip l $ map (^2) l
-- (b)
substitute :: Eq a => a -> a -> [a] -> [a]
substitute x y s = map (\a -> if a == x then y else a) s
-- (c)
numTwins :: Eq a => [a] -> Int
numTwins l = foldr (+) 0
$ map (\(a,b) -> if a==b then 1 else 0)
$ zip (init l) (tail l)
-- (d)
sumPointwise :: Num a => [(a,a)] -> (a,a)
sumPointwise l = (foldr (\(a,_) x -> a+x) 0 l, foldr (\(_,b) x -> b+x) 0 l)
-- (e)
ordPaare :: Ord a => [(a,a)] -> [(a,a)]
ordPaare l = filter (\(a,b) -> a <= b) l
-- (f)
ordered :: Ord a => [a] -> Bool
ordered l = foldr (&&) True
$ map (\(a,b) -> a<b)
$ zip (init l) (tail l)
A6-3
-- (a)
forAll :: (a -> Bool) -> [a] -> Bool
forAll p [] = True
forAll p (x:xs) = (p x) && (forAll p xs)
-- (b)
forAll' :: (a -> Bool) -> [a] -> Bool
forAll' p = foldl (\acc a -> p a && acc) True
-- *Main> :set +s
-- *Main> forAll' odd [1..100000000]
-- False
-- (9.79 secs, 12002599904 bytes)
-- *Main> forAll'' odd [1..100000000]
-- False
-- (0.00 secs, 2608008 bytes)
--
-- Darber hinaus insbesondere auch:
-- *Main> forAll'' odd [1..]
-- False
-- (0.00 secs, 2057752 bytes)
-- Was hingegen mit forAll' nicht endlich ist, daher nicht terminiert. (Nicht
-- versuchen !)
--
-- -> forAll' mit foldl muss erst alle Elemente durcharbeiten, bevor p
-- angewendet werden kann.
-- Bei forAll'' mit foldr kann p auf jedes Element sofort angewendet werden
-- und && kann beim ersten False schon abbrechen, weil False && (...) immer
-- nur wieder False sein kann.
-- => forAll'' mit foldr ist effizienter
A6-4
import SOE
rectPP, circPP, arrowPP :: Point -> Point -> Graphic
openCloseWindow :: IO ()
openCloseWindow = runGraphics (
do w <- openWindow "My Window" (300,300)
drawInWindow w
(withColor Yellow (rectPP (0,0) (100,100)))
drawInWindow w
(withColor Red (circPP (0,0) (100,100)))
drawInWindow w
(withColor Cyan (arrowPP (0,0) (100,100)))
drawInWindow w
(withColor Cyan (arrowPP (100,100) (200,200)))
k <- getKey w -- warte auf Tastatureingabe
closeWindow w
)
rectPP (x1,y1) (x2,y2) = polygon [(x1,y1),(x1,y2),(x2,y2),(x2,y1)]
circPP (x1,y1) (x2,y2) = ellipse (x1,y1) (x2,y2)
arrowPP (x1,y1) (x2,y2) = polygon [(x2,y2),
(x1,((((abs (y2-y1)) `div` 3) * 2) +y1)),
(((((abs (x2-x1)) `div` 3) * 2) +x1),y1),
(x2,y2)]
A7
fun :: [a] -> Int
fun l = foldr (+) 0 . map (/a ((^2)+a) l
A7-1
-- (a)
fun :: Integral a => [a] -> a
fun = sum . map (\a -> a^2 + 1) . filter odd
-- (b)
interleave :: [a] -> [a] -> [a]
interleave xs ys = foldr (\(a,b) succ -> a:b:succ) [] . zip xs $ ys
interleave' = id . id . id . id . id . id . interleave
-- (c)
f1 :: (a -> a -> a) -> [a] -> [(a -> a)]
f1 f xs = map (flip f) xs
f3 = f2 2 ( f1 (^) [1,2,3,4] )
f4 = f2 2 ( f1 (+) [-1,-2,3,44] )
A7-3
import Test.QuickCheck
import Test.QuickCheck.Modifiers
-- (a)
addN, mulN, powerN :: Nat -> Nat -> Nat
A7-4
-- (a)
codeTable :: BinTree a -> Table a
codeTable n = traTree n []
-- (c)
decode :: BinTree a -> [Bit] -> [a]
decode t bl = traTree' t t bl
-- tests
test_codeTable = codeTable (Node (Node (Leaf 'b') (Leaf 'a')) (Leaf 't'))
test_code = code [('b',[L,L]),('a',[L,R]),('t',[R])] "tabat"
test_decode = decode (Node (Node (Leaf 'b') (Leaf 'a')) (Leaf 't')) [R,L,R,L,L,L,R,R]
A8 1,2
{- 8.1
Analyse linke Seite
Bezeichner p x xs Rumpf
Typ 1 2 [2] 3
3= ([4], [5])
-8.2
map foldr
typ (map) = typ (foldr) -> typ (map foldr)
( -> ) -> [] ->[] = (( -> -> ) -> -> [] -> ) -> typ (map foldr)
Substitutionen
typ (map foldr) => [] ->[]
=> -> ->
=> -> [] ->
mglich
------------------------------------
foldr map
typ (foldr) = typ (map) -> typ (foldr map)
( -> -> ) -> -> [] -> = ( -> ) -> [] ->[] -> typ (foldr map)
Substitutionen:
typ (foldr map) => -> [] ->
=> ->
=> [] ->[]
Substitutionen:
typ (foldr foldr) => -> [] ->
=> -> ->
=> -> [] ->
nicht mglich!
-}
A8-3
data BinTree a = Leaf a | Node ( BinTree a ) ( BinTree a )
deriving Show
data LabTree l a = LLeaf a | LNode l ( LabTree l a ) ( LabTree l a )
deriving Show
data STree a = Empty | Split a ( STree a ) ( STree a )
deriving Show
data RoseTree a = RNode a [ RoseTree a ]
deriving Show
data AExp a = Val a | Plus ( AExp a ) ( AExp a )
| Mult ( AExp a ) ( AExp a )
deriving Show
-- (a)
instance Tree (BinTree a) where
subtrees (Node l r) = [l,r]
subtrees (Leaf a) = []
-- (b)
depth :: Tree t => t -> Int
depth t = foldl (\v t ->
let dt = depth t + 1
in max dt v)
0 (subtrees t)
-- tests
btree = Node (Node (Node (Leaf 1) (Leaf 2)) (Leaf 3)) (Leaf 4)
ltree = LNode "a" (LNode "b" (LLeaf 1) (LLeaf 2)) (LLeaf 3)
stree = Split "a" (Split "b" Empty Empty) Empty
rtree = RNode "a" [RNode "b" [RNode "c" [RNode "e" []], RNode "f" []], RNode "d" []]
aexp = Plus (Mult (Val 2) (Val 10)) (Val 3)
A9-2
type Poly = [Float]
-- (a)
scale :: Float -> Poly -> Poly
scale a p = map ((*) a) p
-- (b)
addPoly :: Poly -> Poly -> Poly
addPoly as bs = map (\(a,b) -> a+b) (zip as bs)
-- (c)
mulPoly :: Poly -> Poly -> Poly
mulPoly (a:as) bs = addPoly (scale a bs) (0:mulPoly as bs)
-- (d)
divPoly :: Poly -> Poly -> Poly
divPoly (a:as) (b:bs) = let ab = a/b
in addPoly (ab:zero) (0:divPoly (addPoly (as) (scale (-ab) (bs))) (b:bs))
-- (e)
fibPoly :: Poly
fibPoly = divPoly (1:zero) (1:(-1):(-1):zero)
-- tests
zero :: Poly
zero = (repeat 0)
bsp_poly :: Poly
bsp_poly = (1:2:1:zero)
bsp_poly2 :: Poly
bsp_poly2 = (5:2:1:11:zero)
A9-3
-- (a)
dc :: (a -> Bool) -> (a -> [a]) -> (a-> b) -> (a -> [b] -> b) -> a -> b
dc isTriv spl solv comb xs = if isTriv xs then solv xs
else comb xs [(dc isTriv spl solv comb (head (spl xs))),(dc isTriv spl solv comb (last
(spl xs)))]
foo = [2,0,1,(-1),9]
test = qsort foo == [-1,0,1,2,9]
-- (b)
A10
Tabstops :(
1/1
>
> {--Bildlich: ________________
> | |
> anbn <-------- " " <-------- |map("a"++) |
> | | (map(++"b"))|
> | |________________|
> | |
> |__________________________|
>
>
> --}
> sumOddNum :: [(Int,Int)]
> sumOddNum = (1,1) : (map (\ (x,y) -> ((x + 1), y + (2 * x + 1))) sumOddNum)
2/2
>
> {--Bildlich: ________________
> | |
> sumOddNum <-------- (1,1) <-------- | map(h) |
> | |
> |________________|
> --}
>
>
> --10.2 Algebraische Datenstrukturen, -Kalkl
>
> data LExpr = Var Int | App LExpr LExpr | Lam Int LExpr
> deriving Show
>
> --(a)
>
> free :: LExpr -> [Int]
> free (Var n) = [n]
> free (App x y) = (free x) ++ (free y)
Enthlt Duplikate.
1/1
>
> h :: LExpr -> [Int] -> [Int] -- Expression -> Liste der (lokal) gebundenen Variablen ->
Liste der freien Variablen
> h (Var a) xs | (elem a xs) = []
> | otherwise = [a]
> h (App x y) xs = (h x xs) ++ (h y xs)
> h (Lam a e) xs = h e (a:xs)
>
> --(b)
>
> subst :: Int -> LExpr -> LExpr -> LExpr
> subst n e1 (Var m) | (n==m) = e1
> | otherwise = (Var m)
> subst n e1 (App x y) = (App (subst n e1 x) (subst n e1 y))
> subst n e1 (Lam s t) | (s==n) = (Lam n t)
> | (not (elem n (free e1))) = (Lam s (subst n e1 t))
> | otherwise = error "Fehler: Umbenennung erforderlich!"
2/2
>
>
>
> {--
>
> --C. Bonusaufgaben
>
> --10.4
>
> Durch Komposition:
>
> map :: (a b) [a] [b]
>
> iterate :: (a a) a [a]
>
> ghci> :type map . iterate
> map . iterate :: (a -> a) -> [a] -> [[a]]
> ghci> :type iterate . map
> iterate . map :: (a -> a) -> [a] -> [[a]]
>
> (a) (map iterate)
>
> map :: (x -> y) -> [x] -> [y]
> iterate :: (b -> b) -> b -> [b]
> (.) :: (s -> t) -> (r -> s) -> (r -> t)
>
> a ~ b bedeutet dass sie quvalent sind.
>
> map.iterate
>
> map :: s -> t where
> s ~ x -> y
> t ~ [x] -> [y]
>
> iterate :: r -> s where
> r ~ b -> b
> s ~ b -> [b]
>
> Also
> x -> y ~ s ~ b -> [b]
> =>
> x~b
> y ~ [b]
> t ~ [b] -> [[b]]
>
> map . iterate :: (b -> b) -> [b] -> [[b]]
>
> (b) (iterate map)
>
> map :: (x -> y) -> [x] -> [y]
> iterate :: (b -> b) -> b -> [b]
> (.) :: (s -> t) -> (r -> s) -> (r -> t)
>
> iterate.map
>
> iterate :: r -> s where
> s ~ b -> b
> t ~ b -> [b]
>
> map :: s -> t where
> r ~ x -> y
> s ~ [x] -> [y]
>
> so
> b -> b ~ s ~ [x] -> [y]
> b ~ [x]
> b ~ [y]
> x~y
> r ~ x -> x
> t ~ [x] -> [[x]]
>
> iterate . map :: (x -> x) -> [x] -> [[x]]
>
> Durch Applizieren
>
> (a) (map iterate)
>
> f :: a -> b
> x :: c
> ---------
> f :: b , {a ~ b}
>
> map :: ( a1 b1 ) ([a1] [b1])
> iterate :: (a2 a2) (a2 [a2])
> --------------------------
> { a1 ~ (a2 a2) , b1 ~ (a2 [a2]) }
>
> map iterate :: [a1] [b1] wir bekommen :: [a2 a2] -> [a2 [a2]]
Nicht "ausfhrlich".
>
> (b) (iterate map)
>
> iterate :: ( a2 a2 ) (a2 [a2])
> map :: (a1 b1) ([a1] [b1])
> ---------------------------
> { a2 ~ a1 b1 , a2 ~ [a1] [b1] }
>
> a2 ~ a2 und a1 b1 ~ [a1] [b1]
>
> a1 b1
> [a1] [b1]
> --------------
> { a1 ~ [a1] , b1 ~ [b1] }
>
> (iterate map) in Haskell undefiniert.
>
> *Main> :t map iterate
> map iterate :: [a -> a] -> [a -> [a]]
>
> *Main> :t iterate map
>
> :1:9:
> Occurs check: cannot construct the infinite type: a ~ [a]