Merge branch 'main' of https://gitty.informatik.hs-mannheim.de/1811263/haskell-workshop
commit
d271eb29e9
|
@ -1,19 +1,19 @@
|
||||||
# Aufgabe 1 - Rekursive Implementierung von `map`
|
# Aufgabe 2 - Rekursive Implementierung von `map`
|
||||||
|
|
||||||
## Ziel der Aufgabe
|
## Ziel der Aufgabe
|
||||||
Implementiere die Funktion `map` rekursiv. Die Funktion nimmt eine Funktion `f` und eine Liste `xs` und gibt eine neue Liste zurück, in der `f` auf jedes Element von `xs` angewendet wurde.
|
Implementiere die Funktion `map` rekursiv. Die Funktion nimmt eine Funktion `f` und eine Liste `xs` und gibt eine neue Liste zurück, in der `f` auf jedes Element von `xs` angewendet wurde.
|
||||||
|
|
||||||
## Signatur
|
## Signatur
|
||||||
```haskell
|
```haskell
|
||||||
map :: (a -> b) -> [a] -> [b]
|
myMap :: (a -> b) -> [a] -> [b]
|
||||||
```
|
```
|
||||||
|
|
||||||
## Beispiel Testfäle
|
## Beispiel Testfäle
|
||||||
```haskell
|
```haskell
|
||||||
map (*2) [1, 2, 3] -- [2, 4, 6]
|
myMap (*2) [1, 2, 3] -- [2, 4, 6]
|
||||||
map show [1, 2, 3] -- ["1", "2", "3"]
|
myMap show [1, 2, 3] -- ["1", "2", "3"]
|
||||||
map (const "a") [1, 2, 3] -- ["a", "a", "a"]
|
myMap (const "a") [1, 2, 3] -- ["a", "a", "a"]
|
||||||
map (+1) [] -- []
|
myMap (+1) [] -- []
|
||||||
```
|
```
|
||||||
|
|
||||||
## Anforderungen
|
## Anforderungen
|
||||||
|
@ -22,5 +22,9 @@ map (+1) [] -- []
|
||||||
- Nutze Pattern Matching, um Basis- und Rekursionsfall zu unterscheiden
|
- Nutze Pattern Matching, um Basis- und Rekursionsfall zu unterscheiden
|
||||||
|
|
||||||
## Hinweise
|
## Hinweise
|
||||||
|
<details>
|
||||||
|
<summary>Klicke auf den Pfeil für Hinweise</summary>
|
||||||
|
|
||||||
- Die leere Liste `[]` soll als Basisfall betrachtet werden
|
- Die leere Liste `[]` soll als Basisfall betrachtet werden
|
||||||
- Die Funktion `f` soll auf das erste Element der Liste angewendet und dann mit dem Rest der Liste rekursiv weitergeführt werden
|
- Die Funktion `f` soll auf das erste Element der Liste angewendet und dann mit dem Rest
|
||||||
|
</details>
|
|
@ -1,22 +1,22 @@
|
||||||
-- Aufgabe: Implementiere die rekursive Funktion `map`
|
-- Aufgabe: Implementiere die rekursive Funktion `myMap`
|
||||||
|
|
||||||
-- Funktionssignatur
|
-- Funktionssignatur
|
||||||
map :: (a -> b) -> [a] -> [b]
|
myMap :: (a -> b) -> [a] -> [b]
|
||||||
|
|
||||||
-- TODO: Implementiere die Funktion mit Rekursion
|
-- TODO: Implementiere die Funktion mit Rekursion
|
||||||
map _ [] = undefined
|
myMap _ [] = undefined
|
||||||
map f (x:xs) = undefined
|
myMap f (x:xs) = undefined
|
||||||
|
|
||||||
-- Testfälle
|
-- Testfälle
|
||||||
test1 = map (*2) [1,2,3] == [2,4,6]
|
test1 = myMap (*2) [1,2,3] == [2,4,6]
|
||||||
test2 = map show [1,2,3] == ["1", "2", "3"]
|
test2 = myMap show [1,2,3] == ["1", "2", "3"]
|
||||||
test3 = map (+1) [] == []
|
test3 = myMap (+1) [] == []
|
||||||
test4 = map (const "a") [1,2,3] == ["a", "a", "a"]
|
test4 = myMap (const "a") [1,2,3] == ["a", "a", "a"]
|
||||||
|
|
||||||
-- Hauptfunktion zum Testen
|
-- Hauptfunktion zum Testen
|
||||||
main :: IO ()
|
main :: IO ()
|
||||||
main = do
|
main = do
|
||||||
putStrLn "Teste map-Funktion..."
|
putStrLn "Teste myMap-Funktion..."
|
||||||
print test1
|
print test1
|
||||||
print test2
|
print test2
|
||||||
print test3
|
print test3
|
||||||
|
|
|
@ -5,16 +5,16 @@ Implementiere die Funktion `zip` rekursiv. Die Funktion nimmt zwei Listen und gi
|
||||||
|
|
||||||
## Signatur
|
## Signatur
|
||||||
```haskell
|
```haskell
|
||||||
zip :: [a] -> [b] -> [(a, b)]
|
myZip :: [a] -> [b] -> [(a, b)]
|
||||||
```
|
```
|
||||||
|
|
||||||
## Beispiel Testfäle
|
## Beispiel Testfäle
|
||||||
```
|
```
|
||||||
zip [1,2,3] ['a', 'b', 'c'] -- [(1, 'a'), (2, 'b'), (3, 'c')]
|
myZip [1,2,3] ['a', 'b', 'c'] -- [(1, 'a'), (2, 'b'), (3, 'c')]
|
||||||
zip [1,2] ["eins", "zwei", "drei"] -- [(1, "eins"), (2, "zwei")]
|
myZip [1,2] ["eins", "zwei", "drei"] -- [(1, "eins"), (2, "zwei")]
|
||||||
zip [True, False] [1,2,3] -- [(True,1), (False,2)]
|
myZip [True, False] [1,2,3] -- [(True,1), (False,2)]
|
||||||
zip [] [1,2,3] -- []
|
myZip [] [1,2,3] -- []
|
||||||
zip [1,2,3] [] -- []
|
myZip [1,2,3] [] -- []
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -23,6 +23,11 @@ zip [1,2,3] [] -- []
|
||||||
- Nutze kein zip aus der Standardbibliothek
|
- Nutze kein zip aus der Standardbibliothek
|
||||||
- Die Funktion soll enden, sobald eine der beiden Listen leer ist
|
- Die Funktion soll enden, sobald eine der beiden Listen leer ist
|
||||||
|
|
||||||
|
|
||||||
## Hinweise
|
## Hinweise
|
||||||
- Der Basisfall tritt ein, wenn eine der Listen leer ist
|
<details>
|
||||||
- Kombiniere das erste Element beider Listen zu einem Tupel und rufe zip rekursiv für die restlichen Elemente auf
|
<summary>Klicke auf den Pfeil für Hinweise</summary>
|
||||||
|
|
||||||
|
- Der Basisfall tritt ein, wenn eine der Listen leer ist
|
||||||
|
- Kombiniere das erste Element beider Listen zu einem Tupel und rufe zip rekursiv für die restlichen Elemente auf
|
||||||
|
</details>
|
||||||
|
|
|
@ -1,24 +1,32 @@
|
||||||
-- Aufgabe: Implementiere die rekursive Funktion `zip`
|
-- Aufgabe: Implementiere die rekursive Funktion `myZip`
|
||||||
|
|
||||||
-- Funktionssignatur
|
-- Funktionssignatur
|
||||||
zip :: [a] -> [b] -> [(a, b)]
|
myZip :: [a] -> [b] -> [(a, b)]
|
||||||
|
|
||||||
-- TODO: Implementiere die Funktion mit Rekursion
|
-- TODO: Implementiere die Funktion mit Rekursion
|
||||||
zip [] _ = undefined
|
myZip [] _ = undefined
|
||||||
zip _ [] = undefined
|
myZip _ [] = undefined
|
||||||
zip (x:xs) (y:ys) = undefined
|
myZip (x:xs) (y:ys) = undefined
|
||||||
|
|
||||||
-- Testfälle
|
-- Testfälle mit `null` und expliziten Typannotationen
|
||||||
test1 = zip [1,2,3] ['a', 'b', 'c'] == [(1, 'a'), (2, 'b'), (3, 'c')]
|
test1 :: Bool
|
||||||
test2 = zip [1,2] ["eins", "zwei", "drei"] == [(1, "eins"), (2, "zwei")]
|
test1 = myZip [1,2,3] ['a', 'b', 'c'] == [(1, 'a'), (2, 'b'), (3, 'c')]
|
||||||
test3 = zip [True, False] [1,2,3] == [(True,1), (False,2)]
|
|
||||||
test4 = zip [] [1,2,3] == []
|
|
||||||
test5 = zip [1,2,3] [] == []
|
|
||||||
|
|
||||||
|
test2 :: Bool
|
||||||
|
test2 = myZip [1,2] ["eins", "zwei", "drei"] == [(1, "eins"), (2, "zwei")]
|
||||||
|
|
||||||
|
test3 :: Bool
|
||||||
|
test3 = myZip [True, False] [1,2,3] == [(True,1), (False,2)]
|
||||||
|
|
||||||
|
test4 :: Bool
|
||||||
|
test4 = null (myZip [] [1,2,3])
|
||||||
|
|
||||||
|
test5 :: Bool
|
||||||
|
test5 = null (myZip [1,2,3] [])
|
||||||
-- Hauptfunktion zum Testen
|
-- Hauptfunktion zum Testen
|
||||||
main :: IO ()
|
main :: IO ()
|
||||||
main = do
|
main = do
|
||||||
putStrLn "Teste zip-Funktion..."
|
putStrLn "Teste myZip-Funktion..."
|
||||||
print test1
|
print test1
|
||||||
print test2
|
print test2
|
||||||
print test3
|
print test3
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
# Aufgabe 3 - Fibonacci mit Tail-Rekursion
|
||||||
|
|
||||||
|
## Ziel der Aufgabe
|
||||||
|
Implementiere die Fibonacci-Funktion mit **Tail-Rekursion**, ähnlich wie die `factorialTail`-Funktion. Die Lösung soll eine Hilfsfunktion mit einem Akkumulator verwenden.
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Spoiler: Klicke auf den Pfeil für factorialTail</summary>
|
||||||
|
|
||||||
|
```haskell
|
||||||
|
factorialTail :: Integer -> Integer -> Integer
|
||||||
|
factorialTail 0 acc = acc
|
||||||
|
factorialTail n acc = factorialTail (n - 1) (n * acc)
|
||||||
|
|
||||||
|
factorial :: Integer -> Integer
|
||||||
|
factorial n = factorialTail n 1
|
||||||
|
```
|
||||||
|
</details>
|
||||||
|
|
||||||
|
|
||||||
|
## Signatur
|
||||||
|
```haskell
|
||||||
|
fibonacciTail :: Integer -> Integer -> Integer -> Integer
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Beispiel Testfäle
|
||||||
|
```
|
||||||
|
fibTail 0 -- 0
|
||||||
|
fibTail 1 -- 1
|
||||||
|
fibTail 5 -- 5
|
||||||
|
fibTail 10 -- 55
|
||||||
|
fibTail 15 -- 610
|
||||||
|
```
|
||||||
|
|
||||||
|
## Anforderungen
|
||||||
|
- Implementiere fibonacciTail, eine Hilfsfunktion mit einem Akkumulator
|
||||||
|
- Implementiere fibonacci, die fibonacciTail mit den Startwerten 0 und 1 aufruft
|
||||||
|
- Nutze keine if-Statements, sondern Pattern Matching
|
||||||
|
- Nutze Tail-Rekursion für eine speichereffiziente Lösung
|
||||||
|
|
||||||
|
## Hinweise
|
||||||
|
<details>
|
||||||
|
<summary>Klicke auf den Pfeil für Hinweise</summary>
|
||||||
|
|
||||||
|
- fibonacciTail benötigt drei Parameter:
|
||||||
|
- 1: n (die Anzahl der Schritte)
|
||||||
|
- 2: a (die vorherige Fibonacci-Zahl)
|
||||||
|
- 3: b (die aktuelle Fibonacci-Zahl)
|
||||||
|
- Wenn n == 0 ist, gib a zurück
|
||||||
|
- Wenn n == 1 ist, gib b zurück
|
||||||
|
- Ansonsten rufe die Funktion rekursiv mit n - 1 auf und verschiebe a und b
|
||||||
|
</details>
|
|
@ -0,0 +1,23 @@
|
||||||
|
-- Aufgabe: Implementiere die rekursive Fibonacci-Funktion mit Tail-Rekursion
|
||||||
|
|
||||||
|
fibonacciTail :: Integer -> Integer -> Integer -> Integer
|
||||||
|
-- TODO:
|
||||||
|
|
||||||
|
-- Testfälle
|
||||||
|
test1 = fibonacci 0 == 0
|
||||||
|
test2 = fibonacci 1 == 1
|
||||||
|
test3 = fibonacci 2 == 1
|
||||||
|
test4 = fibonacci 3 == 2
|
||||||
|
test5 = fibonacci 5 == 5
|
||||||
|
test6 = fibonacci 10 == 55
|
||||||
|
|
||||||
|
-- Hauptfunktion zum Testen
|
||||||
|
main :: IO ()
|
||||||
|
main = do
|
||||||
|
putStrLn "Teste fibonacci-Funktion mit Tail-Rekursion..."
|
||||||
|
print test1
|
||||||
|
print test2
|
||||||
|
print test3
|
||||||
|
print test4
|
||||||
|
print test5
|
||||||
|
print test6
|
|
@ -5,7 +5,7 @@ import qualified Distribution.FieldGrammar as Data
|
||||||
--3. gebe die Liste anschließend rückwärts heraus
|
--3. gebe die Liste anschließend rückwärts heraus
|
||||||
|
|
||||||
--Nutze dafür Methoden aus dem module Data.List
|
--Nutze dafür Methoden aus dem module Data.List
|
||||||
--Achtung nutze den richtigen Import, ansonsten kann es zu name clashes kommen
|
--Achtung nutze den richtigen Typ von Import, ansonsten kann es zu name clashes kommen
|
||||||
|
|
||||||
|
|
||||||
--Import
|
--Import
|
||||||
|
@ -13,4 +13,14 @@ import qualified Distribution.FieldGrammar as Data
|
||||||
|
|
||||||
|
|
||||||
--Funktion
|
--Funktion
|
||||||
uniqueReverseList :: (Eq a, Ord a) => --hier in der Zeile fehlt noch etwas;)
|
uniqueReverseList :: --hier in der Zeile fehlt noch etwas. Tipp: man muss Werte auf gleichheit und verhältnis überprüfen können;)
|
||||||
|
|
||||||
|
|
||||||
|
main = do
|
||||||
|
|
||||||
|
let x = uniqueReverseList [2,1,13,1,27,71,59,43] == [71,59,43,27,13,2,1]
|
||||||
|
let y = uniqueReverseList "abcde" == "edcba"
|
||||||
|
|
||||||
|
if x == y
|
||||||
|
then putStrLn "Funktion funktioniert"
|
||||||
|
else putStrLn "Funktion funktioniert nicht"
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
--Tipp: Sinnvoll sind dabei die Verwendung der Funktionen map und reverse, sowie words und unwords
|
--Tipp: Sinnvoll sind dabei die Verwendung der Funktionen map und reverse, sowie words und unwords
|
||||||
|
|
||||||
--Funktion reverseWords
|
--Funktion reverseWords
|
||||||
reverseWords :: String -> String
|
reverseWords ::
|
||||||
|
|
||||||
--I/O-Abschnitt
|
--I/O-Abschnitt
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue