AB1 Nicht-rekursive Ausdrücke

Implementieren Sie die folgenden Funktionen durch nicht-rekursive Ausdrücke (einzige Ausnahme ist Teil 2) und nur unter Verwendung der bereits importierten Funktionen. Außerdem dürfen folgende Sprachkonstrukte nicht verwendet werden: Hinweise (gelten auch für alle weiteren AB):

🎦 Funktionen und Ausdrücke (klicken, um Video anzuschauen) 🎦

Für dieses AB sollten Sie sich die Funktionen map, filter, reduce, foldl und foldr genauer anschauen.

Teil 1

Sie können davon ausgehen, dass arg1 für alle Funktionen in diesem Teil (mit Ausnahme von bigAnd2) mindestens ein Element enthält.
minimum  :: [Int] -> Int
maximum  :: [Int] -> Int
Die Funktionen geben ein minimales bzw. maximales Element der Liste arg1 zurück.
bigAnd   :: [Bool] -> Bool 
bigOr    :: [Bool] -> Bool 
bigXor   :: [Bool] -> Bool 
Die Funktion bigAnd gibt wahr zurück gdw. alle Elemente in arg1 wahr sind.
Die Funktion bigOr gibt wahr zurück gdw. mindestens ein Element in arg1 wahr ist.
Die Funktion bigXor gibt wahr zurück gdw. eine ungerade Anzahl von Elementen in arg1 wahr sind.
sum :: [Int] -> Int
alternatingSum  :: [Int] -> Int
alternatingSum2 :: [Int] -> Int
Die Funktion sum gibt die Summe aller Elemente in arg1 zurück.
Die Funktion alternatingSum gibt die alternierende Summe aller Elemente in arg1 zurück. Für [1,2,3,4,5] ist das 1 - 2 + 3 - 4 + 5.
Die Funktion alternatingSum2 ist eine Variante, bei der + und - vertauscht werden. Für [1,2,3,4,5] ist das 1 + 2 - 3 + 4 - 5.
bigAnd2 :: [Bool] -> Bool
Die Funktion bigAnd2 gibt wahr zurück gdw. alle Elemente in der Liste wahr sind oder die Liste leer ist.

Teil 2

Für diesen Teil dürfen (und müssen) Sie rekursive Ausdrücke verwenden.
infiniteList :: Int -> [Int] 
listFromTo   :: Int -> Int -> [Int] 
Die Funktion infiniteList gibt die unendliche Liste zurück, welche alle Int beginnend ab arg1 in aufsteigender Reihenfolge enthält.
Die Funktion listFromTo gibt die Liste zurück, welche alle Int beginnend von arg1 bis arg2 in aufsteigender Reihenfolge enthält. Beispiele:
fibTree :: (Tree Int) 
fTree   :: (Int -> Int) -> (Tree Int) 
Die Funktion fibTree ist der unendliche binäre Baum, welcher die Fibonacci-Sequenz (1, 1, 2, 3, 5, 8, 13, ...) beschreibt. Das erste Kind ist der entsprechende Wert aus der Sequenz.
Beispiel
1
  1
  2
    1
    3
      2
      4
        3
        5
          5
          6
            8
            7
              13
              ...
Die Funktion fTree ist eine Verallgemeinerung von fibTree für beliebige Sequenzen. Das erste Kind eines Knotens mit dem Wert i enthält den Wert f i, wobei f = arg1.
Beispiel
1
  f 1
  2
    f 2
    3
      f 3
      4
        f 4
        5
          f 5
          6
            f 6
            7
              f 7
              ...

Teil 3

crossList    :: [a] -> [b] -> [(a,b)]
genCrossList :: [[a]] -> [[a]]
Die Funktion crossList ist das kartesische Produkt zweier Listen. Beispiel: Die Funktion genCrossList ist das kartesische Produkt verallgemeinert auf beliebig viele Argumente, welche als Elemente der Liste arg1 repräsentiert werden. Sie können davon ausgehen, dass arg1 mindestens ein Element enthält. Beispiele:
Tipp zu genCrossList (falls Sie Probleme haben, diese Funktion zu implementieren, versuchen Sie den folgenden Code zu vervollständigen)
genCrossList lst = foldl crossList2 acc lst'
  where
    crossList2 x y = map g ?
      where
        g (lst,el) = append el lst  
    lst' = ?
    acc = map f ?
      where
        f el = [el]

primes :: Int -> [Int]
Die Funktion primes gibt die ersten arg1 (≥ 0) Primzahlen zurück. Beispiele:
Tipp zu primes Schreiben Sie eine Funktion ohne Eingabeparameter, welche die unendliche Liste aller Primzahlen zurückgibt.

Teil 4

type Base = Int
toDigits   :: Base -> Int -> [Int]
fromDigits :: Base -> [Int] -> Int
length     :: Base -> Int -> Int
Die Funktion toDigits wandelt die Zahl arg2 (≥ 0) in eine Liste von Ziffern zur Basis arg1 (≥ 2) um. Das erste Element der Liste ist die Ziffer mit dem höchsten Stellenwert (für Basis 2 also das most significant bit). Beispiele: Die Funktion fromDigits ist die Umkehrfunktion von toDigits. Das heißt, es gilt fromDigits b (toDigits b x) == x. Sie können davon ausgehen, dass jedes Element aus arg2 zwischen 0 und (arg1 - 1) liegt und arg2 mindestens ein Element enthält. Beispiele: Die Funktion length gibt die Länge der Zahl arg2 zur Basis arg1 zurück. Beispiele: Eine Zahl bestehend aus \(n \geq 1\) Ziffern \(x_1, x_2, \dots, x_n\) zur Basis \(b \geq 2\) ist definiert als $$\sum_{i=1}^n x_i \cdot b^{i-1}$$
Hinweis zu find und zip
Tipp zu toDigits Schreiben Sie eine Funktion, welche die i-te Ziffer einer Zahl für eine gegebene Basis berechnet.