{----------------------------------------------------------
--    Datei mit Beispielen zu Funktionen hoeherer Ordnung
-----------------------------------------------------------
-- einige in Prelude.hs vordefinierte Funktionen hoeherer Ordnung:

-- Funktionskomposition
(.)            :: (b -> c) -> (a -> b) -> (a -> c)
(f . g) x       = f (g x)

-- Listentransformation
map              :: (a -> b) -> [a] -> [b]
map f xs          = [ f x | x <- xs ]

-- Listenfilterung
filter           :: (a -> Bool) -> [a] -> [a]
filter p xs       = [ x | x <- xs, p x ]

-- Listenfaltung
foldr            :: (a -> b -> b) -> b -> [a] -> b
foldr f z []      = z
foldr f z (x:xs)  = f x (foldr f z xs)

foldl            :: (a -> b -> a) -> a -> [b] -> a
foldl f z []      = z
foldl f z (x:xs)  = foldl f (f z x) xs
-----------------------------------------------------------}
import Data.Char

-- Textverschluesselung nach der Caesarmethode
code            :: Char -> Char
code x 
    | letter x  =  xox 
    | otherwise =  x
    where 
        upperLetter x = x >= 'A' && x <= 'Z'
        lowerLetter x = x >= 'a' && x <= 'z'
        letter x = upperLetter x || lowerLetter x
        ox  =  ord x + 13
        xox =  if    (upperLetter x && ox > ord 'Z') 
                  || (lowerLetter x && ox > ord 'z')
               then chr (ox - 26)
               else chr ox

caesar     :: String -> String 
caesar str =  map code str


-- Beispiel für Linksfaltung

string2int :: String -> Int
string2int = foldl aux 0
 where aux x c 
         | '0' <= c && c <= '9' 
           = x * 10 + (ord c - ord '0')
         | otherwise
           = error (c:" ist keine Ziffer")

-- als Rechtsfaltung
string2intR :: String -> Int
string2intR = fst . foldr aux (0,1)
 where aux c (x,w) 
         | '0' <= c && c <= '9' 
           = ((ord c - ord '0') * w + x, 10*w)
         | otherwise
           = error (c:" ist keine Ziffer")


 

-- Kompakte Funktionsdefinitionen mittels Komposition

addList :: Num a => [a] -> [a] -> [a]
addList =  curry (map (uncurry (+)) . uncurry zip)
-- besser: addList = zipWith (+)


capCount :: String -> Int
capCount = length . filter (isUpper . head) . words




-- Polynomauswertung
type Polynom = [Double]

eval :: Double -> Polynom -> Double
eval x p = foldl (\ y a -> y * x + a) 0.0 p
