diff --git a/lab/01-intro-lab.lhs b/lab/01-intro-lab.lhs new file mode 100644 index 0000000000000000000000000000000000000000..da99d59e6e33db05753d375cedf5635ccbf23982 --- /dev/null +++ b/lab/01-intro-lab.lhs @@ -0,0 +1,127 @@ +\chapter{Einleitung} +\begin{aufgabe} +Zeigen Sie mehrere m"ogliche Auswertungen f"ur `hoch4 (2 + 3). + +> quadrat x = x * x + +> hoch4 x = quadrat (quadrat x) + +hoch4 (2+3) += +hoch4 5 += +quadrat (quadrat 5) += +quadrat (5 * 5) += +quadrat 25 += +25*25 += +625 + +hoch4 (2+3) += +quadrat (quadrat (2+3)) += +quadrat (2+3) * quadrat (2+3) += +(2+3)*(2+3) * (2+3)*(2+3) += +5*5*5*5 += +625 + +\end{aufgabe} + +\begin{aufgabe} +Definieren Sie eine Funktion `summe`, die eine +Liste von Zahlen addiert. + +> summe :: [Integer] -> Integer +> summe [] = 0 +> summe (x:xs) = x + summe xs + +Geben Sie einige Testf"alle an und vergleichen Sie mit der Standardfunktion +`sum`. +\end{aufgabe} + +\begin{aufgabe} +Definieren Sie eine Funktion `laenge`, die die Laenge einer Liste berechnet. + +> laenge :: [Integer] -> Integer +> laenge [] = 0 +> laenge (_:xs) = 1 + laenge xs + +Testfall: +λ> laenge [1..5] +5 +Finden Sie weitere Testf"alle und vergleichen Sie mit der Standardfunktion +`length`. + +Vergleichen Sie mit der Definition aus der vorherige Aufgabe. +\end{aufgabe} + +\begin{aufgabe} +Zeigen Sie, dass `produkt [x] = x` f"ur beliebiges x gilt. + +produkt [x] += { [x] = x : [] } +x * produkt [] += +x * 1 += +x + +\end{aufgabe} + +\begin{aufgabe} +Zeigen Sie eine Auswertung von `quick [3, 5, 2, 1, 4]`. + +quick [3, 5, 2, 1, 4] += +quick [2,1] ++ [3] ++ quick [5,4] += +quick [1] ++ [2] ++ quick [] ++ [3] ++ quick [4] ++ [5] ++ quick [] +quick [] ++ [1] ++ quick [] ++ [2] ++ [] ++ [3] ++ quick [] ++[4] + quick [] ++ [5] ++ [] += +[] ++ [1] ++ [] ++ [2] ++ [] ++ [3] ++ [] ++ [4] ++ [] ++ [5] ++ [] += +[1,2,3,4,5] + + +\end{aufgabe} + +\begin{aufgabe} +Geben Sie die Funktion Fakult"at rekursiv an. + +> fakultaet' :: Integer -> Integer +> fakultaet' 0 = 1 +> fakultaet' x = x * fakultaet' (x-1) + +Welches Problem gibt es bei Ihrer Definition? +\end{aufgabe} + +\begin{aufgabe} +Geben Sie eine Definition der Funktion der Fibonacci-Zahlen an. +Zur Erinnerung: $f_0 = 0, f_1 = 1, f_n = f_{n-1} + f_{n-2}$ + +> fibonacci :: Integer -> Integer +> fibonacci 0 = 0 +> fibonacci 1 = 1 +> fibonacci x = fibonacci (x-1) + fibonacci (x-2) + +\end{aufgabe} + +\begin{aufgabe} +Definieren Sie die Funktionen `head` und `tail`, die das erste Element bzw. +den Rest einer Liste ganzer Zahlen berechnen. + +> head' :: [Integer] -> Integer +> head' (x:_) = x + + +> tail' :: [Integer] -> [Integer] +> tail' (_:xs) = xs + +\end{aufgabe} diff --git a/lab/02-types.lhs b/lab/02-types.lhs new file mode 100644 index 0000000000000000000000000000000000000000..66499ae0d0dca8cb302a887ace9720240846692b --- /dev/null +++ b/lab/02-types.lhs @@ -0,0 +1,42 @@ +\chapter{Typen} + +> import Data.List + +\begin{aufgabe} +Geben Sie den Typ der folgenden Ausdr"ucke an. Pr"ufen Sie Ihre Antwort mit GHCi. +\begin{enumerate} +\item [ 'o', 'h', 'm' ] +\item ( 'o', 'h', 'm' ) +\item [ (), () ] +\item [ ( 'o', ()), ('h', ())] +\item ( ['o', 'h'], [(), ()] ) +\item [ 1, 3.14, 6.5 ] +\item ( 1, 3.14, 6.5 ) +\item [ head, last, (!! 2) ] +\end{enumerate} +\end{aufgabe} + +\begin{aufgabe} +Schreiben Sie eine Definition, die den folgenden Typ hat: +\begin{enumerate} +\item zahlen :: [Integer] +\item wahrheiten :: [[Bool]] +\item add :: Int -> Int -> Int -> Int +\item zip3' :: [a] -> [b] -> [c] -> [(a, b, c)] +\item apply :: (a -> b) -> a -> b +\end{enumerate} +Bei welchen Typen gibt es nur eine L"osung? +\end{aufgabe} + +\begin{aufgabe} +Geben Sie den Typ der folgenden Funktionen an: +\begin{enumerate} +\item second xs = head (tail xs) +\item swap (x, y) = (y, x) +\item pair x y = (x, y) +\item palindrome xs = reverse xs == xs +\item twice f x = f (f x) +\end{enumerate} +Geben Sie auch die Klassenconstraints an, sovern ueberladene Operatoren +verwendet werden. +\end{aufgabe} diff --git a/lab/03-functions.lhs b/lab/03-functions.lhs new file mode 100644 index 0000000000000000000000000000000000000000..ce191b3d55dfff43af69605e661a88db2a42bc1e --- /dev/null +++ b/lab/03-functions.lhs @@ -0,0 +1,89 @@ +\chapter{Funktionen} +\begin{aufgabe} +Weshalb kann im allgemeinen der Funktionstyp keine Eq Instanz besitzen? Wir +betrachten zwei Funktionen als gleich, wenn sie vom gleichen Typ sind (!) und +f"ur stets f"ur gleiche Eingaben auch gleiche Ergebnisse liefern. Diese +Eigenschaft hei"st extensionale Gleichheit der Funktion. +\end{aufgabe} + +\begin{aufgabe} +Verwenden Sie Funktionen aus Data.List, um die Funktion + +> halbieren :: [a] -> ([a], [a]) +> halbieren = undefined + +zu schreiben, die eine Liste gerader L"ange in der Mitte teilt. Finden sie +f"ur ungerade L"ange eine sinnvolle Spezifikation. + +Schreiben Sie nun eine Funktion, die zwei sortierte Listen zu einer sortierten +Liste verschmilzt. + +> merge :: Ord a => ([a],[a]) -> [a] +> merge = undefined + +Schreiben Sie nun unter Verwendung der beiden Funktionen halbieren und merge +eine Funktion mergesort. + +> mergesort :: Ord a => [a] -> [a] +> mergesort = undefined + +\end {aufgabe} + +\begin{aufgabe} +Definieren Sie die Funktion third :: [a] -> a, die das dritte Element einer +Liste liefert, wenn es existiert, mittels: +\begin{enumerate} +\item head und tail, +\item dem Listenindexoperator !!, +\item Patternmatch. +\end{aufgabe} + +\begin{aufgabe} +Schreiben Sie eine sichere tail Funktion, die sich bei einer nichtleeren Liste +verh"alt wie tail und bei einer leeren Liste, eine leere Liste zur"uck gibt. +Verwenden Sie, wenn erforderlich die Funktionen tail und null :: [a] -> Bool, +um safetail zu definieren: +\begin{enumerate} +\item mit einem bedingten Ausdruck, +\item mit guarded equations +\item mit pattern matching +\end{enumerate} + +\end{aufgabe} + +\begin{aufgabe} +Geben Sie wie in der Vorlesung vier verschiedene Wege an, um die Disjunktion +(oder) auf Bool zu implementieren. +\end{aufgabe} + +\begin{aufgabe} +Betrachten Sie den folgenden Datentyp f"ur eine dreiwertige Logik: + +> data Drei = Nein | Jein | Ja +> deriving (Show, Eq) + +Geben Sie zunaechst mit der "Wahrheitstabellen"-Methode eine Definition +f"ur die Funktionen not, and und or. Ueberlegen Sie sich, was der Wert +Jein bedeutet und definieren Sie die Funktionen dann entsprechend. + +> tnot :: Drei -> Drei +> tnot = undefined + +> tand :: Drei -> Drei -> Drei +> tand = undefined + +> tor :: Drei -> Drei -> Drei +> tor = undefined + +Betrachten Sie die Wahrheitstabelle und finden Sie eine kompaktere Definition +mit Patterns f"ur and: + +> tand' :: Drei -> Drei -> Drei +> tand' = undefined + +Finden Sie eine kompaktere Definition f"ur or, indem Sie Guards verwenden. + +> tor' :: Drei -> Drei -> Drei +> tor' = undefined + +\end{aufgabe} diff --git a/lab/04-comprehensions.lhs b/lab/04-comprehensions.lhs new file mode 100644 index 0000000000000000000000000000000000000000..ee27ab9c42132d85b88d3944a8c2610d2d09ef25 --- /dev/null +++ b/lab/04-comprehensions.lhs @@ -0,0 +1,53 @@ +\chapter{List Comprehensions} + +\begin{aufgabe} +Schreiben Sie eine Funktion, die alle pythagoreischen Zahlentripel bis zu +einer maximalen Gr"o"se n ausgibt. Achten Sie darauf, dass keine doppelten +Tripel (z. B. (3,4,5) ~ (4,3,5) ) vorkommen. Verwenden Sie eine List +Comprehension. Zur Erinnerung: \[ a^2 + b^2 = c^2 \]. + +> pythagoras :: Integer -> [(Integer, Integer, Integer)] +> pythagoras n = [(a, b, c) | a <- [1..n], b <- [a..n], c <- [b..n], a^2 + b^2 == c^2] + +\end{aufgabe} + +\begin{aufgabe} + +Schreiben Sie eine Funktion, die alle Quadrupel bis zu einer maximalen Gr"o"se ausgibt, die folgende Gleichung erf"ullen: +\[ a^2 + b^2 = c^2 + d^2 \]. + +Vermeiden Sie wie in der vorherigen Aufgabe Quadrupel, die im wesentlichen +gleich sind. + +> quadratsummen :: Integer -> [(Integer, Integer, Integer, Integer)] +> quadratsummen n = [(a, b, c, d) | a <- [1..n], b <- [a..n], c <- [b..n], d <- [c..n], a^2 + b^2 == c^2 + d^2] + +\end{aufgabe} + +\begin{aufgabe} +Schreiben Sie die Funktion replicate aus Data.List als List Comprehension. + +> replicate' :: Int -> a -> [a] +> replicate' n x = [x | _ <- [1..n]] + +\end{aufgabe} + +\begin{aufgabe} + +Formulieren Sie das Skalarprodukt zweier Vektoren, die als Liste implementiert +sind. Verwenden Sie an geeignerter Stelle eine List Comprehension. + +\[ x * y = \sum_{i=0}^{n-1}(x_i * y_i) \] + +> skalar :: [Double] -> [Double] -> Double +> skalar x y = sum [ x_i * y_i | (x_i, y_i) <- zip x y] + +\end{aufgabe} + +\begin{aufgabe} +Schreiben Sie die Funktion partition aus Data.List als List Comprehension. + +> partition' :: (a -> Bool) -> [a] -> ([a], [a]) +> partition' p xs = ([x | x <- xs, p x], [x | x <- xs, not (p x)]) + +\end{aufgabe}