Sie sind auf Seite 1von 21

Haskell Lsungen Rita Loogen Marburg SS15

A1-1

-- returns a list of all factor of n, including n


-- takes at start n, m=1, l=[]
factor :: Int -> Int -> [Int] -> [Int]
factor n m l | m `elem` l = l
| n `mod` m /= 0 = factor n (m+1) l
| n `mod` m == 0 = factor n (m+1) (n `div` m : m : l)

-- returns True if the sum of the factors of n is n


-- since factor adds n to the list, sum has to be n*2 for True
-- takes n > 1
vollkommen :: Int -> Bool
vollkommen n | n < 2 = False
| otherwise = sum (factor n 1 []) == n*2

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)

picCol :: Int -> Picture -> Picture


picCol n p | n==1 = invert n p
| otherwise = above (invert n p) (picCol (n-1) p)

picRow :: Int -> Picture -> Picture


picRow n p | n==1 = invert n p
| otherwise = aside (invert n p) (picRow (n-1) p)

invert :: Int -> Picture -> Picture


invert n p | (n `mod` 2) == 0 = p
| otherwise = invertColour p

chessboard :: Int -> Picture -> Picture


chessboard n p | n < 1 = error "n has to be > 0"
| otherwise = picSquare n p

-- b)
dots = ["..",
".."]

picSquare' :: Int -> Picture -> Picture


picSquare' n p | n == 1 = p
| otherwise = picCol' n n p

picCol' :: Int -> Int -> Picture -> Picture


picCol' n z p | n==1 = picRow' z n p
| otherwise = above (picRow' z n p) (picCol' (n-1) z p)

picRow' :: Int -> Int -> Picture -> Picture


picRow' n z p | n == 1 = invert' n z p
| otherwise = aside (invert' n z p) (picRow' (n-1) z p)

invert' :: Int -> Int -> Picture -> Picture


invert' n z p | n == z = invertColour p
| otherwise = p

diag, cross :: Int -> Picture


diag n | n < 1 = error "n has to be > 0"
| otherwise = picSquare' n dots

cross n | n < 1 = error "n has to be > 0"


| otherwise = superimpose (picSquare' n dots)
(flipH (picSquare' n dots))
A2-1

-- 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)

subsequence :: Eq a => [a] -> [a] -> Bool


subsequence [] _ = True
subsequence _ [] = False
subsequence xs ys = xs == take (length xs) ys || subsequence xs (tail ys)

-- b)
grep :: String -> [String] -> [String]
grep xs yss | null xs = []
| otherwise = filter (not . null)
(map (subseqReturn xs) yss)

subseqReturn :: String -> String -> String


subseqReturn xs ys | subsequence xs ys = ys
| otherwise = []

grep' :: String -> [String] -> [String]


grep' _ [] = []
grep' st (st':sts) | subsequence st st' = st':(grep' st sts)
| otherwise = grep' st sts

A3-1
-- a)

-- takes a list cs, an index i (starting from 1 !), and


-- a counter n
-- returns n chars from index i on
slice :: String -> Int -> Int -> String
slice [] _ _ = []
slice cs i n = take n (drop (i - 1) cs)

-- takes a list cs, an index i (starting from 0 !), and


-- a counter n
-- returns n chars from index i on
slice' :: String -> Int -> Int -> String
slice' [] _ _ = []
slice' cs i n = take n (drop i cs)

-- b)

-- with explicit recursion


count :: Char -> String -> Int
count _ [] =0
count c (l:cs) | c == l = 1 + (count c cs)
| otherwise = count c cs

-- 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)]

getRmTuppel :: [a] -> Int -> (a,[a])


getRmTuppel x i = ((x !! i), (deleteElemAtIndex i 0 x))

deleteElemAtIndex :: Int -> Int -> [a] -> [a]


deleteElemAtIndex i c x | c >= len = []
| c == i = [] ++ (deleteElemAtIndex i (c+1) x)
| otherwise = (x !! c):(deleteElemAtIndex i (c+1) x)
where len = length x

A3-3

import Formula

-- a)
vars :: Formula -> [String]
vars f = uniq (vars' f)

vars' :: Formula -> [String]


vars' (Var s) = [s]
vars' (Not f) = vars' f
vars' (And f g) = vars' f ++ vars' g
vars' (Or f g) = vars' f ++ vars' g

uniq :: [String] -> [String]


uniq [] = []
uniq (x:xs) | x `elem` xs = uniq xs
| otherwise = (x:(uniq xs))
-- b)
assignments :: [String] -> [Assignment]
assignments a = map reverse (comp [] a) where
comp a [] = [a]
comp a (x:xs) = (comp ((x,True):a) xs) ++ ( comp ((x,False):a) xs)

-- c)
truthTable :: Formula -> [(Assignment,Bool)]
truthTable f = zip (assignments (vars f)) (map (f2b f) (assignments (vars f)))

f2b :: Formula -> Assignment -> Bool


f2b (Var s) l = find s l
f2b (Not f) l = not (f2b f l)
f2b (And f g) l = (f2b f l) && (f2b g l)
f2b (Or f g) l = (f2b f l) || (f2b g l)

find :: String -> Assignment -> Bool


find s ((var,b):xs) | var == s = b
| otherwise = find s xs
A4-1

data Tree a = Empty | Node a (Tree a) (Tree a)


deriving Show
-- a)
elements :: Tree a -> [a]
elements (Node val Empty Empty) = val:[]
elements (Node val a Empty) = val:elements a
elements (Node val Empty b) = val:elements b
elements (Node val a b) = val:elements a ++ elements b

-- 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)

isBalanced :: Tree a -> Bool


isBalanced t = (depth t == depthMin t)

-- 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)

balanceFill :: Tree a -> Tree (Maybe a)


balanceFill = balanceFill' . tree2mtree

balanceFill' :: Tree (Maybe a) -> Tree (Maybe a)


balanceFill' t | isBalanced t = t
| otherwise = balanceFill' . insert $ t
where insert (Node x Empty b) = Node x (Node Nothing Empty Empty) b
insert (Node x a Empty) = Node x a (Node Nothing Empty Empty)
insert (Node x a b) = if (depthMin a < depthMin b)
then (Node x (insert a) b)
else (Node x a (insert b))
A4-2

-- a)
del :: Eq a => a -> [a] -> [a]
del _ [] = []
del c (x:xs) | x == c = del c xs
| otherwise = x:del c xs

count :: Eq a => a -> [a] -> Int


count _ [] = 0
count c (x:xs) | x == c = 1 + count c xs
| otherwise = count 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)))

run_Tests = do quickCheck prop_LengthInits


quickCheck prop_LengthInits'

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)

add :: Expr -> Expr -> Expr


add (Val x) (Val y) = Val (x+y) -- (add1)
add x y = Add x y -- (add2)

mult :: Expr -> Expr -> Expr


mult (Val x) (Val y) = Val (x*y) -- (mult1)
mult x y = Mult x y -- (mult2)

-- (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"]

raetsel :: String -> IO ()


raetsel w = loop w $ take (length w) (repeat '-')

loop :: String -> String -> IO ()


loop w q = do putStr (q ++ "\n")
putStr ("Buchstabe? ")
c <- getChar
putStr ("\n")
let r = unhide w q c
if r == w then exit w
else loop w r
where exit :: String -> IO ()
exit w = putStr(w ++ " --> Glueckwunsch!\n")

unhide :: String -> String -> Char -> String


unhide [] [] _ = []
unhide (w:ws) (q:qs) c | w == c || w == toUpper c = w:unhide ws qs c
| otherwise = q:unhide ws qs c

A6-1

addLineNumbers :: String -> String


addLineNumbers s = unlines $
map (\(l,s) -> show l ++ ": " ++ s) $ zip [1..] $ lines s

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

forAll'' :: (a -> Bool) -> [a] -> Bool


forAll'' p = foldr (\a acc -> 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

f2 :: a -> [(a -> a)] -> [a]


f2 y xs = map (\f -> f y) 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

data Nat = Zero | Succ Nat deriving (Show)

foldN :: a -> (a -> a) -> Nat -> a


foldN z _ Zero =z
foldN z s (Succ n) = s (foldN z s n)

-- (a)
addN, mulN, powerN :: Nat -> Nat -> Nat

toInt :: Nat -> Int


toInt x = foldN 0 (+1) x

toNat :: Int -> Nat

A7-4

data BinTree a = Leaf a | Node (BinTree a) (BinTree a) deriving Show


data Bit = L | R deriving Show
type Table a = [ (a, [Bit]) ]

-- (a)
codeTable :: BinTree a -> Table a
codeTable n = traTree n []

traTree (Leaf a) s = [(a,s)]


traTree (Node l r) s = (traTree l (s ++ [L])) ++ (traTree r (s ++ [R]))
-- (b)
code :: Eq a => Table a -> [a] -> [Bit]
code _ [] = []
code [] _ = []
code t (e:es) = (unjust (lookup e t)) ++ (code t es)
where unjust (Just a) = a
unjust Nothing = error "Not in table"

-- (c)
decode :: BinTree a -> [Bit] -> [a]
decode t bl = traTree' t t bl

traTree' t (Node l r) (L:dl) = traTree' t l dl


traTree' t (Node l r) (R:dl) = traTree' t r dl
traTree' t (Leaf n) dl = n:(traTree' t t dl)
traTree' t n [] = []

-- 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

break1 :: (a -> Bool) -> [a] -> ([a], [a])


break1 p [] = ([] , [])
break1 p (x:xs) = let (ys , zs) = break1 p xs
in if p x then ([] , x:xs) else (x:ys , zs)

{- 8.1
Analyse linke Seite
Bezeichner p x xs Rumpf
Typ 1 2 [2] 3

Analyse rechte Seite


typ (ys,zs) = typ(e1)
typ let (ys , zs) = break p xs in if p x then ([] , x:xs) else (x:ys , zs) = typ (e2)

3= ([4], [5])

-8.2
map foldr
typ (map) = typ (foldr) -> typ (map foldr)
( -> ) -> [] ->[] = (( -> -> ) -> -> [] -> ) -> typ (map foldr)

Substitutionen
typ (map foldr) => [] ->[]
=> -> ->
=> -> [] ->

Fr (map foldr) ergibt sich demnach der Typ


[ -> -> ] ->[ -> [] -> ]

mglich
------------------------------------
foldr map
typ (foldr) = typ (map) -> typ (foldr map)
( -> -> ) -> -> [] -> = ( -> ) -> [] ->[] -> typ (foldr map)

Substitutionen:
typ (foldr map) => -> [] ->
=> ->
=> [] ->[]

Fr (foldr map) ergibt sich demnach der Typ


[] ->[] -> [ -> ] -> [] ->[]
= [] -> [ -> ] -> []
mglich
-------------------------------------
foldr foldr
typ (foldr) = typ (foldr) -> typ (foldr foldr)
( -> -> ) -> -> [] -> = ( -> -> ) -> -> [] -> -> typ (foldr foldr)

Substitutionen:
typ (foldr foldr) => -> [] ->
=> -> ->
=> -> [] ->

Fr (foldr foldr) ergibt sich demnach der Typ


-> [] -> -> [ -> -> ] -> -> [] ->
=
-> [ -> -> ] ->

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

class Tree t where


subtrees :: t -> [t]

-- (a)
instance Tree (BinTree a) where
subtrees (Node l r) = [l,r]
subtrees (Leaf a) = []

instance Tree (LabTree a b) where


subtrees (LNode x l r) = [l,r]
subtrees (LLeaf x) = []

instance Tree (STree a) where


subtrees (Split a l r) = [l,r]
subtrees Empty = []

instance Tree (RoseTree a) where


subtrees (RNode a rs) = rs

instance Tree (AExp a) where


subtrees (Val a) = []
subtrees (Plus l r) = [l,r]
subtrees (Mult l r) = [l,r]

-- (b)
depth :: Tree t => t -> Int
depth t = foldl (\v t ->
let dt = depth t + 1
in max dt v)
0 (subtrees t)

size :: Tree t => t -> Int


size t = (length $ trees t) +1

-- hier werden nur echte teilbume bestimmt


trees :: Tree t => t -> [t]
trees t = foldl (\l st -> l ++ [st] ++ trees st) [] (subtrees t)

-- ein baum ist sein eigener teilbaum


trees' :: Tree t => t -> [t]
trees' t = [t] ++ trees 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)

test_scale = take 5 $ scale 2 bsp_poly


test_addPoly = take 5 $ addPoly bsp_poly bsp_poly
test_mulPoly = take 15 $ mulPoly bsp_poly bsp_poly
test_divPoly = take 15 $ divPoly (mulPoly bsp_poly bsp_poly2) bsp_poly
test_divPoly2 = test_divPoly == (take 15 $ bsp_poly2)
test_fibPoly = take 15 $ fibPoly

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)))]

qsort :: Ord a => [a] -> [a]


qsort = dc null spliT id combine where
spliT (x:xs) = [[y|y <- xs, y < x], [y|y <- xs, y >= x]]
combine (x:_) [ys1,ys2] = ys1 ++ x:ys2

foo = [2,0,1,(-1),9]
test = qsort foo == [-1,0,1,2,9]

-- (b)

data Formula = Var String | Not Formula


| And Formula Formula
| Or Formula Formula
deriving (Eq, Show)

truthValue = dc triv split solv combine

triv (Var x) = True


triv x = False

solv (Var f) = lookup' f

split (And a b) = [a,b]


split (Or a b) = [a,b]
split (Not a) = [a,undefined]

combine (And _ _) [a,b] = a && b


combine (Or _ _) [a,b] = a || b
combine (Not _) [a,_] = not a

lookup' ("A") = True


lookup' ("B") = True
lookup' _ = False
-- tests
bspFormel = And (Var "A") (Not (Var "B"))
bspFormel2 = Or (Var "A") (Not (Var "B"))

A10
Tabstops :(

> --10.1 Lazy Evaluation / Prozessnetze


>
>
> anbn :: [String]
> anbn = "" : map ("a"++) (map (++"b") anbn)

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.

> free (Lam n x) = h x [n]

Einfach alle freien auer n ;)

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

Das war gemeint. Lieber nachfragen anstatt zuviel arbeiten ;)

>
> (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]

> Expected type: (a -> b) -> a -> b


> Actual type: (a -> b) -> [a] -> [b]
> In the first argument of 'iterate', namely 'map'
> In the expression: iterate map
>
> :1:9:
> Occurs check: cannot construct the infinite type: b ~ [b]
> Expected type: (a -> b) -> a -> b
> Actual type: (a -> b) -> [a] -> [b]
> In the first argument of 'iterate', namely 'map'
> In the expression: iterate map
>

Das könnte Ihnen auch gefallen