{- aufgabe 1 - a) - funktionen als first-class-citizen - - funktionen im mathematischen sinne - - umsetzung des lambda kalküls - - rein funktional: - - keine seiteneffekte - - keine destruktiven updates - - b) - - keine objekte, da objekte zustaende repräsentieren - - mathematische funktionen anstatt sequentieller anweisungen - - c) - - funktion mit mehreren argumenten wird zu mehreren funktionen mit - jeweils einem argument transformiert. An der typsignatur von Haskell - ersichtlich: - foo :: Int -> (Int -> (Int -> Int)) - foo a b c = a + b + c - d) - funktion die als argument eine andere funktion kriegt, oder eine - funktion zurück gibt. - e) - lazy, strikt - f) - haskells art der überladung - - typklasse beinhaltet bestimmte funktionen die für andere andere - datentypen implementiert werden können. -} ------------ -- aufgabe 2 ------------ -- a) greater_quad :: Int -> Int -> Int greater_quad x y = if x > y then x * x else y * y -- b) -- Elemente eines Datentyps können mit Hilfe von `case' analysiert werden. Statt -------------------------------------------------------------------- -- > elem a [] = False -- > elem a (b:x) = a==b || elem a x -------------------------------------------------------------------- -- kann `elem' auch (weniger elegant) mit Hilfe von `case' definiert werden. -------------------------------------------------------------------- -- > elem = \a y -> case y of -- > [] -> False -- > b:x -> a==b || elem a x -------------------------------------------------------------------- -- Ein `case'-Ausdruck bietet sich an, wenn das Ergebnis eines Funktionsaufrufs weiterverarbeitet werden soll. -- Mit _ lässt sich ein Default-case definieren. Dieser muss an letzter Stelle stehen. -- Quelle: http://www.informatik.uni-bonn.de/~ralf/teaching/Hskurs_3.html#SEC25 ackermann_case :: Int -> Int -> Int ackermann_case x y = case x of 0 -> y + 1 _ -> case y of 0 -> ackermann_case (x - 1) 1 _ -> ackermann_case (x - 1) (ackermann_case x (y - 1)) -- c) ackermann_pattern :: Int -> Int -> Int ackermann_pattern 0 y = y + 1 ackermann_pattern (x + 1) 0 = ackermann_pattern x 1 ackermann_pattern (x + 1) (y + 1) = ackermann_pattern x (ackermann_pattern (x + 1) y) -- d) ackermann_guard :: Int -> Int -> Int ackermann_guard x y | x == 0 = y + 1 | y == 0 = ackermann_guard (x - 1) 1 | otherwise = ackermann_guard (x - 1) (ackermann_guard x (y - 1)) ------------ -- aufgabe 3 ------------ -- a) div_list :: Int->[Int] div_list d = [ x | x <- [ 1..d ], d `mod` x == 0 ] -- b) add_head_tail :: [Int] -> Int add_head_tail (x : xs) = x + last xs where last (x : []) = x last (_ : xs) = last xs -- c) my_max :: Int -> Int -> Int my_max x y = if x > y then x else y find_max :: [Int] -> Int find_max (x : xs) = _find_max x xs where _find_max x [] = x _find_max x (y : ys) = _find_max (my_max x y) ys -- d) (+++) :: [a] -> [a] -> [a] x +++ [] = x [] +++ y = y (x : xs) +++ y = x : (xs +++ y) -- e) my_reverse :: [a] -> [a] my_reverse [] = [] my_reverse (x : xs) = (my_reverse xs) ++ [x] ------------ -- aufgabe 4 ------------ -- a) my_map :: (a -> b) -> [a] -> [b] my_map _ [] = [] my_map f (x : xs) = (f x) : my_map f xs -- b) my_filter :: (a -> Bool) -> [a] -> [a] my_filter _ [] = [] my_filter p (x : xs) | p x = x : my_filter p xs | otherwise = my_filter p xs -- c) sum1 = foldl (+) 0 -- d) sum2 = foldr (+) 0