module LazyEvaluation where import Prelude hiding (repeat, iterate, concat) {- Wiederholung Akkumulatortechnik: fibiter :: Int -> Int -> Int -> Int fibiter fibn fibnp1 n = if n == 0 then fibn else fibiter fibnp1 (fibn + fibnp1) (n - 1) fib :: Int -> Int fib n = fibiter 0 1 n -} -- Generator function for Fibonacci number fibgen :: Int -> Int -> [Int] fibgen n1 n2 = n1 : fibgen n2 (n1 + n2) -- Returns an inifinite list of all Fibonacci numbers fibs :: [Int] fibs = fibgen 0 1 -- Return the n-th Fibonacci number fib :: Int -> Int fib n = fibs !! n -- Returns an infinite list containing the given element repeat :: a -> [a] repeat x = x : repeat x {- Wiederholung $-Operator: infixr 0 $ ($) :: (a -> b) -> a -> b f $ x = f x -} -- Returns an infinite list of repeated function applications to a given start -- value, e.g.: iterate f x = [x, f x, f (f x), f (f (f x)), ...] iterate :: (a -> a) -> a -> [a] iterate f x = x : iterate f (f x) -------------------------------------------------------------------------------- {- Das folgende Beispiel zeigt, dass textuell doppelt vorkommende Ausdrücke auch zweimal ausgewertet werden. Doppelte Berechnungen werden durch Lazy Evaluation also nur vermieden, wenn die Verdoppelung des Ausdrucks durch doppelte Variablenvorkommen auf einer rechten Seite zustande kommt. -} plusfib10000000 :: Int plusfib10000000 = fib 10000000 + fib 10000000 double :: Int -> Int double x = x + x plusfib10000000' :: Int plusfib10000000' = double (fib 10000000) -------------------------------------------------------------------------------- -- Returns an infinite list of ones. ones :: [Int] ones = 1 : ones -- Infinite list of numbers starting with a given value -- from n = [n ..] from :: Int -> [Int] from n = n : from (n + 1) -- iterate (+ 1) n -- iterate (\x -> x + 1) n -- fromThen 0 2 = [0,2,4,6,...] -- fromThen n1 n2 = [n1, n2 ..] fromThen :: Int -> Int -> [Int] fromThen n1 n2 = let d = n2 - n1 in n1 : fromThen (n1 + d) (n2 + d) -- iterate (\x -> x + (n2 - n1)) n1 -- iterate (+ (n2 - n1)) n1 -- fromTo n m = [n .. m] fromTo :: Int -> Int -> [Int] fromTo n m = if n>m then [] else n : fromTo (n + 1) m -- fromThenTo n1 n2 m = [n1, n2 .. m] fromThenTo :: Int -> Int -> Int -> [Int] fromThenTo n1 n2 m = let d = n2 - n1 in if d >= 0 && n1 > m || d < 0 && n1 < m then [] else n1 : fromThenTo (n1 + d) (n2 + d) m data Color = Red | Blue | Yellow deriving (Eq, Ord, Enum, Bounded, Show) -- Returns the factorial of a given number factorial :: Int -> Int factorial n = foldr (*) 1 [1 .. n] numberedChars :: [(Int, Char)] numberedChars = zip [1 ..] ['a' .. 'z'] numLines :: [String] numLines = map (uncurry (++)) (zip (map show [1 ..]) (repeat ". Zeile")) -------------------------------------------------------------------------------- -- { x * x | x ∈ {1, .., 100}, x ungerade } oddSquares :: [Int] oddSquares = [ x | x <- [1 .. 100], odd x ] pairs :: [(Int, Int)] pairs = [(i, j) | i <- [1 .. 3], j <- [2 .. 4], i /= j] inits' :: [[Int]] inits' = [ [0 .. n] | n <- [0 ..]] factorials :: [Int] factorials = map (foldr (*) 1) [ [1 .. n] | n <- [1 ..] ] -- You can also have a constant expression in a list comprehension: twos :: [Int] twos = [2 | _ <- [1 ..]] concat' :: [[a]] -> [a] concat' xss = [y | ys <- xss, y <- ys]