-- größtest Element einer Liste ----------------------------------------------------

--maxList1 :: (Bounded a, Ord a) => [a] -> a
maxList1 :: [Int] -> Int
maxList1 = foldl max (minBound)

maxList2 :: [Int] -> Int
maxList2 = foldr max (minBound)



-- Liste unverändert ---------------------------------------------------------------

listId1 :: [a] -> [a]
listId1 = foldl myconcat []
	  where myconcat xs x = xs ++ [x]

listId2 :: [a] -> [a]
listId2 = foldr myconcat []
	  where myconcat x xs = (x:xs) 



-- Liste umdrehen ------------------------------------------------------------------

myrev :: [a] -> [a]
myrev = foldl (\xs x -> (x:xs)) []



-- Prüfbit berechnen (True, wenn Anzahl True's in Liste ungerade, sonst False) -----

bit :: [Bool] -> Bool
bit = foldl (\a b -> a /= b) False



-- Vektoren addieren ---------------------------------------------------------------

type Vector = [Float]

vAdd :: Vector -> Vector -> Vector
vAdd = zipWith (+)



-- Standardskalarprodukt -----------------------------------------------------------

skp :: Vector -> Vector -> Float
skp v1 v2 = mysum (zipWith (*) v1 v2)
            where mysum = foldl (+) 0



-- Hornerschema mit foldl ----------------------------------------------------------

horner1 :: [Int] -> Int -> Int
horner1 digits base = foldl (\z d -> z * base + d) 0 digits



-- Hornerschema mit until ----------------------------------------------------------

horner2 :: [Int] -> Int -> Int
horner2 digits base = fst (until p f (0, digits))
                      where p (_, []) = True
                            p _       = False
                            f (z, (d:ds)) = (z * base + d, ds)

-- Termininierungsbeweis und Schleifeninvariante
-- in den Unterlagen zum Tutorium