Compare commits
22 Commits
stripped-g
...
stripped
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1820b61f40 | ||
|
|
ec81776d50 | ||
|
|
87b8d91fe2 | ||
|
|
049802ff92 | ||
|
|
a16fa8e5ae | ||
|
|
e21d6aaf3f | ||
|
|
952e477666 | ||
|
|
1f33467433 | ||
|
|
8ee83bd02b | ||
|
|
5fefc209f6 | ||
|
|
a5034b1812 | ||
|
|
3feb500826 | ||
|
|
f45e3b192f | ||
|
|
4b7eb36c5e | ||
|
|
7ea86009d9 | ||
|
|
4f138f5995 | ||
|
|
3f9c4bed57 | ||
|
|
8a695659ae | ||
|
|
4c0c549d85 | ||
|
|
eaf2a52956 | ||
|
|
fc718cdfd0 | ||
|
|
b09e11aef9 |
@@ -4,5 +4,6 @@
|
||||
> 6 * 5.0
|
||||
> "Hello" ++ " world"
|
||||
> "Haskell" > "C++"
|
||||
> 3 > 4
|
||||
> True && False
|
||||
\end{haskellcode*}
|
||||
@@ -5,5 +5,5 @@
|
||||
\item \ifger{da das Typsystem extrem mächtig ist, sind die Fehlermeldungen des type-checkers manchmal verwirrend und zeigen nicht immer den Fehler, den man erwartet hätte}{because the type system is extremely powerful/complex, type error messages can be very confusing and don't always show the error you expected}
|
||||
\item \ifger{(noch) keine premium-IDE mit allen möglichen features}{no premium-like IDE with every possible feature (yet)}
|
||||
\item \ifger{dynamisches linking ist noch WIP und man hat sehr häufig ABI-Inkompatibilität}{dynamic linking is sort of WIP yet, lots of ABI breakage}
|
||||
\item \ifger{da der Groteil der IT in imperativen Programmiersprachen denkt, ist es häufig schwierig pseudo-code für funktionale Sprachen zu finden, weshalb man letztendlich Algorithmen reverse-engineeren muss}{because most of the world thinks in imperative style languages, it's often difficult to find pseudo-code for functional style languages, so you end up reverse-engineering algorithms}
|
||||
\item \ifger{da der Großteil der IT in imperativen Programmiersprachen denkt, ist es häufig schwierig pseudo-code für funktionale Sprachen zu finden, weshalb man letztendlich Algorithmen reverse-engineeren muss}{because most of the world thinks in imperative style languages, it's often difficult to find pseudo-code for functional style languages, so you end up reverse-engineering algorithms}
|
||||
\end{itemizep}
|
||||
@@ -14,6 +14,7 @@ GHCi...
|
||||
\vspace{\baselineskip}
|
||||
\\
|
||||
\ifger{Was ist eine mögliche Typsignatur dieser Funktion?}{What is a possible type signature for this function?}
|
||||
\pause
|
||||
\begin{haskellcode}
|
||||
f :: Int -> Int
|
||||
f x = x * x
|
||||
|
||||
@@ -8,4 +8,7 @@ sumPair :: (Int, Int) -> Int
|
||||
sumPair (x, y) = x + y
|
||||
\end{haskellcode}
|
||||
\pause
|
||||
\ifger{Hinweis: wir benutzen}{Note: we use} \hinline{(x, y)} \ifger{als Notation sowohl für den Typ als auch die Definition! Dies sind trotzdem 2 verschiedene Dinge. Wir können auch Triple, Quadruple etc. haben.}{notation for both the type and the definition! Those are still two different things. We can also have triples, quadruples etc.}
|
||||
\ifger{Hinweis: wir benutzen}{Note: we use} \hinline{(x, y)} \ifger{als Notation sowohl für den Typ als auch die Definition! Dies sind trotzdem 2 verschiedene Dinge. Wir können auch Triple, Quadruple etc. haben.}{notation for both the type and the definition! Those are still two different things. We can also have triples, quadruples etc.}
|
||||
\vspace{\baselineskip}\\
|
||||
\pause
|
||||
\ifger{Frage: Unterschied zu Listen?}{Question: difference to lists?}
|
||||
@@ -6,7 +6,7 @@ isZero 0 = True
|
||||
isZero x = False
|
||||
\end{haskellcode}
|
||||
\vspace{\baselineskip}
|
||||
\ifger{D.h. wenn wir eine \hinline{0} übergeben, bekommen wir \hinline{True} zurück. Wenn wir keine \hinline{0} übergeben, dann bekommen wir \hinline{False} zurück und der Eingabewert wird quasi nicht weiter betrachtet.}{So if we pass it \hinline{0}, we get \hinline{True}. If we do not pass \hinline{0}, we get \hinline{False} and the value we passed gets basically ignored.}
|
||||
\ifger{D.h. wenn wir eine \hinline{0} übergeben, bekommen wir \hinline{True} zurück. Wenn wir keine \hinline{0} übergeben, dann bekommen wir \hinline{False} zurück, denn \hinline{x} in Zeile 3 ist ebenso pattern matching, allerdings matcht es jede Zahl.}{So if we pass it \hinline{0}, we get \hinline{True}. If we do not pass \hinline{0}, we get \hinline{False}, because \hinline{x} in line 3 is pattern matching as well, but matches every Int.}
|
||||
\vspace{\baselineskip}
|
||||
\\
|
||||
\pause
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
\begin{itemizep}
|
||||
\item \ifger{keine}{none}...
|
||||
\item {laziness}
|
||||
\end{itemizep}
|
||||
@@ -3,6 +3,7 @@
|
||||
\item \ifger{was ist referenzielle Transparenz?}{What is referential transparency?}
|
||||
\item \ifger{kann ich referenzielle Transparenz mit Seiteneffekten haben?}{Can you have referential transparency with side effects?}
|
||||
\item \ifger{wovon hängt die Ausgabe einer Haskell Funktion ab?}{What does the output of a haskell function depend on?}
|
||||
\item \ifger{Was ist call-by-name? Was ist call-by-need?}{What is call-by-name? What is call-by-need?}
|
||||
\item \ifger{was ist}{What is} laziness?
|
||||
\item \ifger{Wann werden Typen in Haskell geprüft?}{When are types checked in haskell?}
|
||||
\item \ifger{Was sind die Unterschiede zwischen Listen und Tuplen?}{What are the differences between lists and pairs?}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
\begin{itemize}
|
||||
\item \textbf{GHC}: \ifger{das ist der Haskell Compiler}{this is the Haskell compiler}
|
||||
\item \textbf{GHCi}: \ifger{das ist die interaktive Compiler-Umgebung, ähnlich der ruby shell \emph{irb}}{this an interactive environment of GHC, similar to the interactive ruby shell \emph{irb}}
|
||||
\item \textbf{The Haskell Platform}: \ifger{eine Kollektion die GHC, GHCi und Standardbibliotheken beinhaltet}{a collection including GHC, GHCi and basic libraries}
|
||||
\end{itemize}
|
||||
\ifger{Siehe}{Go to}\footnote{\url{https://www.haskell.org/platform}}\\
|
||||
\ifger{Für Haskell IDEs, siehe}{For haskell IDEs, see}\footnote{\url{https://wiki.haskell.org/IDEs}}
|
||||
\item \textbf{The Haskell Platform}: \ifger{eine Kollektion die GHC, GHCi und Standardbibliotheken beinhaltet}{a collection including GHC, GHCi and basic libraries}\footnote{\url{https://www.haskell.org/platform}}
|
||||
\item \ifger{Haskell IDEs}{haskell IDEs}\footnote{\url{https://wiki.haskell.org/IDEs}}
|
||||
\end{itemize}
|
||||
@@ -4,4 +4,7 @@
|
||||
\item \ifger{unendliche Datenstrukturen sind möglich, sowohl rekursive als auch nicht-rekursive}{infinite data structures are now possible (recursive and non-recursive)}
|
||||
\item \ifger{neue Kontrollstrukturen können sehr leicht durch Definieren von Funktionen erzeugt werden, wir benötigen nicht unbedingt if-then-else}{defining new control structures by just defining a function (since not everything is evaluated... who needs if-then-else anyway?)}
|
||||
\item \ifger{sehr wichtig für die Programmierung mit Komposition (z.b. Funktionskomposition) und Effizienz}{important for compositional programming and efficiency}
|
||||
\end{itemizep}
|
||||
\end{itemizep}
|
||||
\slidep
|
||||
\vspace{\baselineskip}
|
||||
\ifger{Frage:}{Question:} call-by-value? call-by-reference? call-by-need?
|
||||
@@ -13,7 +13,4 @@
|
||||
\item \ifger{Parallelisierung}{parallelism}
|
||||
\item \ifger{Denken in Gleichungen und hohes Refactoring-Potenzial}{equational reasoning and refactoring}
|
||||
\item \ifger{weniger Bugs!}{less bugs!}
|
||||
\end{itemizep}
|
||||
\slidep
|
||||
\vspace{\baselineskip}
|
||||
\ifger{Frage:}{Question:} call-by-value? call-by-reference? call-by-need?
|
||||
\end{itemizep}
|
||||
@@ -4,6 +4,7 @@
|
||||
\item pure
|
||||
\item lazy
|
||||
\item \ifger{statisch typisiert (und typsicher)}{statically typed (and truly type-safe)}
|
||||
\item general purpose language
|
||||
\item \ifger{sogar}{even} garbage collected
|
||||
\item \ifger{die beste imperative Programmiersprache der Welt (was??)}{the world's finest imperative language (what??)}
|
||||
\end{itemize}
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
\slide{./content/VL2_polymorphism1.tex}
|
||||
\slide{./content/VL2_polymorphism2.tex}[ (cnt.)]
|
||||
\slide{./content/VL2_polymorphism3.tex}[ (cnt.)]
|
||||
|
||||
|
||||
\section{\ifger{Andere Arten der Funktionsdefinition}{More ways to define functions}}
|
||||
@@ -53,6 +54,7 @@
|
||||
|
||||
\subsection{\ifger{Schlussfolgerung}{Conclusion}}
|
||||
\slide{./content/VL2_currying5.tex}
|
||||
\slide{./content/VL2_currying5.1.tex}[ (cnt.)]
|
||||
|
||||
\subsection{Partial application}
|
||||
\slide{./content/VL2_currying6.tex}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
\vspace{\baselineskip}
|
||||
\\
|
||||
\ifger{Aus der Mathematik wissen wir bereits, dass:}{From maths we already know that:}\\
|
||||
$(g \circ f)(x) = g(f(x))$
|
||||
$(f \circ g)(x) = f(g(x))$
|
||||
\vspace{\baselineskip}
|
||||
\\
|
||||
\pause
|
||||
@@ -14,7 +14,7 @@ composedFunction x = (f . g) x
|
||||
-- is evaluated first
|
||||
composedFunction x = f . g $ x
|
||||
|
||||
-- and same again, remember that 'f x ='
|
||||
-- and same again, remember that 'g x ='
|
||||
-- is just syntax sugar
|
||||
-- omitting the x here is also called eta reduction
|
||||
composedFunction = f . g
|
||||
|
||||
@@ -10,4 +10,4 @@ addInt x y = x + y
|
||||
addInt :: (Int, Int) -> Int
|
||||
addInt (x, y) = x + y
|
||||
\end{haskellcode}
|
||||
\ifger{was im Grunde der Sache sogar recht nahe kommt.}{which is actually pretty close.}
|
||||
\ifger{was im Grunde der Sache sogar recht nahe kommt. Denn die Beziehung beider Schreibweisen ist eigentlich schon \textbf{Currying}.}{which is actually pretty close. Because the connection between both syntax is exactly that: \textbf{currying}.}
|
||||
@@ -3,16 +3,21 @@ $f(x, y) = y / x$
|
||||
\vspace{\baselineskip}
|
||||
\\
|
||||
\pause
|
||||
\ifger{Um diese Funktion für $x = 2$ und $y = 3$ zu berechnen würden wir einfach einsetzen:}{In order to evaluate the function for $x = 2$ and $y = 3$ we would do:}\\
|
||||
$f(2, 3) = 2 / 3$\\
|
||||
\ifger{und fertig sein.}{and be done.}
|
||||
\ifger{Um diese Funktion für $x = 2$ und $y = 3$ zu berechnen würden wir normalerweise einfach einsetzen:}{In order to evaluate the function for $x = 2$ and $y = 3$ we would usually just do:}\\
|
||||
$f(2, 3) = 3 / 2$
|
||||
\vspace{\baselineskip}
|
||||
\\
|
||||
\pause
|
||||
\ifger{Allerdings, wie wäre es wenn wir nur für $x$ einsetzen und dadurch eine neue Funktion definieren. Da $x$ weg ist, können wir schreiben:}{However, how about we just put in $x$ first and make a new function. Since $x$ is gone, we can write:}\\
|
||||
$g(y) = f(2, y) = y / 2$
|
||||
\ifger{Allerdings, wie wäre es wenn wir daraus eine Funktion mit nur dem Argument $x$ formulieren:}{However, how about we first make a function that only has $x$ as an argument:}\\
|
||||
$h(x) = y \mapsto f(x, y)$\\
|
||||
\ifger{Dies ist bereits die curried Variante von $f$!}{This is a curried version of $f$!}
|
||||
\vspace{\baselineskip}
|
||||
\\
|
||||
\pause
|
||||
\ifger{Und erst in einem zweiten Schritt lösen wir die Gleichung indem wir $y$ in $g(y)$ einsetzen:}{And in a second step we solve the function $g(y)$:}\\
|
||||
\ifger{Wenn wir jetzt für $x = 2$ einsetzen, können wir eine weitere Funktion definieren:}{If we fix $x = 2$ we can make another function:}\\
|
||||
$g(y) = h(2) = y \mapsto f(2, y) = y / 2$
|
||||
\vspace{\baselineskip}
|
||||
\\
|
||||
\pause
|
||||
\ifger{Und erst im letzten Schritt lösen wir die Gleichung indem wir $y$ in $g(y)$ einsetzen:}{And in the last step we solve the function $g(y)$:}\\
|
||||
$g(3) = f (2, 3) = 3 / 2$
|
||||
@@ -1,7 +1,5 @@
|
||||
\ifger{Wir können uns das ganze auch geometrisch vorstellen:}{You can also imagine this geometrically:}\\
|
||||
$z = f(x, y)$ \ifger{ist}{is} 3-dimensional. \ifger{Wenn wir für die Variable $x$ einsetzen bekommen wir im Grunde eine 2-dimensionale Funktion (die Schnittebene). Wenn wir dann für $y$ einsetzen, bekommen wir den eigentlich Punkt $z$.}{If you fix the variable $x$ you'll make things 2-dimensional (the intersecting plane). If you then fix $y$ you'll get an actual point $z$.}
|
||||
\vspace{\baselineskip}
|
||||
\\
|
||||
\includegraphics*[scale=0.4]{./images/Grafico_3d_x2+xy+y2.png}
|
||||
\\
|
||||
$z = f(x, y)$ \ifger{hat eine 2-dimensionale Definitionsmenge}{has a 2-dimensional set of definitions}. \ifger{Wenn wir für die Variable $y$ einsetzen legen wir quasi die Schnittebene fest und bekommen als Funktion die Schnittkurve (1-dimensionale Definitionsmenge). Die Schnittkurve $s(x) = f(x, y)|_{y = 1}$ können wir jetzt durch einsetzen von $x$ auswerten, um $z$ zu berechnen.}{If we fix the variable $y$, then we've defined the intersecting plane and get a function for the intersection curve $s(x) = f(x, y)|_{y = 1}$ (1-dimensional set of definitions). If we fix $x$ here, we'll get our $z$.}\\
|
||||
\includegraphics*[width=0.5\textwidth]{./images/Grafico_3d_x2+xy+y2.png}
|
||||
\vspace{\baselineskip}\\
|
||||
\ifger{Für jeden dieser Schritte können wir eine echte neue Funktion definieren. Das funktioniert mit einer beliebigen Anzahl von Dimensionen/Argumenten.}{For every of these steps we can define a real new function. This scales up to any number of dimensions/arguments.}
|
||||
16
VL2/content/VL2_currying5.1.tex
Normal file
16
VL2/content/VL2_currying5.1.tex
Normal file
@@ -0,0 +1,16 @@
|
||||
\ifger{Also, wenn wir in Haskell scheinbar mehrere Argumente einer Funktion übergeben, steckt immer Currying dahinter. Es erzeugt eine Reihe von Zwischenfunktionen (oder anonyme Funktionen) mit jeweils einem Argument und evaluiert diese dann schrittweise.}{So, if we seemingly pass multiple arguments into a function, then there is always currying behind it. It creates those intermediate/anonymous functions, all with one argument only, and then evaluates them stepwise.}
|
||||
|
||||
\begin{haskellcode}
|
||||
-- this is more or less just syntax sugar...
|
||||
f x y z = x + y + z
|
||||
-- ...for this
|
||||
f = \x -> (\y -> (\z -> x + y + z)) -- right-associative
|
||||
\end{haskellcode}
|
||||
\ifger{Frage: was passiert, wenn wir nur $x = 3$ übergeben?}{Question: what happens if we just pass $x = 3$?}
|
||||
\vspace{\baselineskip}
|
||||
\\
|
||||
\pause
|
||||
\ifger{Wieso nicht das?}{Why not this?}
|
||||
\begin{haskellcode}
|
||||
f = \x -> x + (\y -> y + (\z -> z)) -- no!
|
||||
\end{haskellcode}
|
||||
@@ -8,7 +8,7 @@ $f' : A_1 \mapsto (A_2 \mapsto (\ ...\ (A_n \mapsto B)))$
|
||||
\vspace{\baselineskip}
|
||||
\\
|
||||
\pause
|
||||
\ifger{Die Klammern hier sind äußerst wichtig! Currying ist \emph{rechts}-assoziativ, d.h. die folgenden 2 Typsignaturen in Haskell sind äquivalent:}{Did you just notice the braces? They are \textbf{very} important! So, currying is \emph{right}-associative which means that these two signatures are equivalent:}
|
||||
\ifger{Die Klammern hier sind äußerst wichtig! Currying ist \emph{rechts}-assoziativ, d.h. die folgenden 2 Typsignaturen sind äquivalent:}{The braces are \textbf{very} important! It means currying is \emph{right}-associative and these these two signatures are equivalent:}
|
||||
\begin{haskellcode}
|
||||
f :: Int -> Int -> Int
|
||||
f :: Int -> (Int -> Int)
|
||||
@@ -16,4 +16,6 @@ f :: Int -> (Int -> Int)
|
||||
-- but this is NOT the same
|
||||
f :: (Int -> Int) -> Int
|
||||
\end{haskellcode}
|
||||
\ifger{Auf der anderen Seite ist Funktionsanwendung \emph{links}-assoziativ, d.h.}{On the other hand function application is \emph{left}-associative, so} \hinline{f 3 2} \ifger{ist nur die Kurzform für}{is just a shorthand of} \hinline{(f 3) 2}. \ifger{Macht Sinn?}{Makes sense?}
|
||||
\ifger{Auf der anderen Seite ist Funktionsanwendung \emph{links}-assoziativ, d.h.}{On the other hand function application is \emph{left}-associative, so} \hinline{f 3 2} \ifger{ist nur die Kurzform für}{is just a shorthand of} \hinline{(f 3) 2}.
|
||||
\vspace{\baselineskip}
|
||||
\\
|
||||
@@ -3,17 +3,14 @@
|
||||
\begin{haskellcode}
|
||||
addInt :: Int -> Int -> Int
|
||||
addInt x y = x + y
|
||||
-- which is equivalent to this as we already know
|
||||
addInt = \x -> (\y -> x + y)
|
||||
|
||||
addTwo :: Int -> Int
|
||||
addTwo = addInt 2
|
||||
\end{haskellcode}
|
||||
\ifger{Warum haben wir nicht \hinline{addTwo x = ...} geschrieben? Wieso sollten wir? Wir haben \hinline{addInt} ein Argument übergeben, also ist die Arität (im Beispiel vorher Dimension) einer weniger und damit ist noch ein Argument notwendig um den endgültigen Wert zu bekommen.}{You probably noticed that we did not write \hinline{addTwo x = ...}, but why would we? We gave \hinline{addInt} one argument, so the arity (we called it dimension in the gemoetrical example) is one less, but there is still one parameter left we can pass in.}
|
||||
\pause
|
||||
\ifger{Der Grund warum wir \hinline{x} auslassen können ist, dass}{The reason we can omit the \hinline{x} here is that}
|
||||
\begin{haskellcode}
|
||||
f x y z = ...
|
||||
\end{haskellcode}
|
||||
\ifger{nur syntax sugar ist für}{is just syntax sugar for}
|
||||
\begin{haskellcode}
|
||||
f = \x -> (\y -> (\z -> ... )) -- right-associative, ofc
|
||||
\end{haskellcode}
|
||||
\ifger{Wir haben \hinline{addInt} ein Argument übergeben, also ist die Arität (im Beispiel vorher Dimension) einer weniger und damit ist noch ein Argument notwendig um den endgültigen Wert zu bekommen.
|
||||
\vspace{\baselineskip}\\
|
||||
Oder in anderen Worten: wir haben der Zwischenfunktion, die Currying für uns erstellt hat, lediglich den Namen \hinline{addTwo} gegeben.}{We gave \hinline{addInt} one argument, so the arity (we called it dimension in the gemoetrical example) is one less, but there is still one argument left we can pass in.
|
||||
\vspace{\baselineskip}\\
|
||||
Or in other words: we just gave the intermediate function that currying created for us the name \hinline{addTwo}. That's it.}\vspace{\baselineskip}\\
|
||||
@@ -1,4 +1,4 @@
|
||||
\ifger{Wie am Anfang dieses Kapitels bereits gesagts sind diese beiden Funktionen sehr ähnlich:}{As said in the beginning of this section, these two look pretty similar:}
|
||||
\ifger{Wie am Anfang dieses Kapitels bereits gesagt sind diese beiden Funktionen sehr ähnlich:}{As said in the beginning of this section, these two look pretty similar:}
|
||||
\begin{haskellcode}
|
||||
f :: Int -> Int -> Int
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ filter :: (a -> Bool) -> [a] -> [a]
|
||||
\pause
|
||||
\begin{haskellcode}
|
||||
filter :: (a -> Bool) -> [a] -> [a]
|
||||
filter f [] = []
|
||||
filter f [] = []
|
||||
filter f (x:xs)
|
||||
| f x = x : filter f xs
|
||||
| otherwise = filter f xs
|
||||
|
||||
@@ -6,20 +6,20 @@ sum :: [Int] -> Int
|
||||
\pause
|
||||
\begin{haskellcode}
|
||||
sum :: [Int] -> Int
|
||||
sum [] = 0
|
||||
sum [] = 0
|
||||
sum (x:xs) = x + sum xs
|
||||
\end{haskellcode}
|
||||
\pause
|
||||
\ifger{Oder das Produkt:}{Or the product:}
|
||||
\begin{haskellcode}
|
||||
prod :: [Int] -> Int
|
||||
prod [] = 1
|
||||
prod [] = 1
|
||||
prod (x:xs) = x * prod xs
|
||||
\end{haskellcode}
|
||||
\pause
|
||||
\ifger{Oder die Länge:}{Or the length:}
|
||||
\begin{haskellcode}
|
||||
length :: [a] -> Int
|
||||
length [] = 0
|
||||
length [] = 0
|
||||
length (x:xs) = 1 + length xs
|
||||
\end{haskellcode}
|
||||
@@ -1,14 +1,14 @@
|
||||
\ifger{Um es kurz zu machen, die abstrakte Lösung ist:}{To cut the story short, the abstract solution looks like this:}
|
||||
\begin{haskellcode}
|
||||
fold :: b -> (a -> b -> b) -> [a] -> b
|
||||
fold z f [] = z
|
||||
fold z f (x:xs) = x `f` (fold z f xs)
|
||||
fold :: (a -> b -> b) -> b -> [a] -> b
|
||||
fold f z [] = z
|
||||
fold f z (x:xs) = x `f` (fold f z xs)
|
||||
\end{haskellcode}
|
||||
Whoa! What's going on here?\\
|
||||
\ifger{Schauen wir genauer hin...}{Let's see...}
|
||||
\begin{itemizep}
|
||||
\item \hinline{z} \ifger{ist was die Funktion zurückgibt, wenn die Liste leer ist}{is what we return if the list is empty}
|
||||
\item \hinline{f} \ifger{ist unsere Funktion}{is our function} (\ifger{z.b.}{e.g.} \hinline{(*)} \ifger{oder}{or} \hinline{(+)})
|
||||
\item \hinline{z} \ifger{ist was die Funktion zurückgibt, wenn die Liste leer ist}{is what we return if the list is empty}
|
||||
\item \ifger{das letzte Argument ist die eigentliche Liste, auf der wir arbeiten}{and the last remaining argument is the actual list we are working on}
|
||||
\end{itemizep}
|
||||
\slidep
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
\pause
|
||||
\begin{haskellcode}
|
||||
sum :: [Int] -> Int
|
||||
sum xs = fold 0 (\x y -> x + y) xs
|
||||
sum xs = fold (\x y -> x + y) 0 xs
|
||||
-- a Haskeller would write
|
||||
sum = fold 0 (+)
|
||||
sum = fold (+) 0
|
||||
|
||||
prod :: [Int] -> Int
|
||||
prod xs = fold 1 (\x y -> x * y) xs
|
||||
prod xs = fold (\x y -> x * y) 1 xs
|
||||
|
||||
length :: [a] -> Int
|
||||
length xs = fold 0 (\x y -> 1 + y) xs
|
||||
length xs = fold (\x y -> 1 + y) 0 xs
|
||||
\end{haskellcode}
|
||||
@@ -1,7 +1,7 @@
|
||||
\ifger{Lösung:}{Solution:}
|
||||
\begin{haskellcode}
|
||||
addTwo :: [Int] -> [Int]
|
||||
addTwo [] = []
|
||||
addTwo [] = []
|
||||
addTwo (x:xs) = (x + 2) : addTwo xs
|
||||
\end{haskellcode}
|
||||
\pause
|
||||
@@ -9,14 +9,14 @@ addTwo (x:xs) = (x + 2) : addTwo xs
|
||||
\pause
|
||||
\begin{haskellcode}
|
||||
square :: [Int] -> [Int]
|
||||
square [] = []
|
||||
square [] = []
|
||||
square (x:xs) = (x * x) : square xs
|
||||
\end{haskellcode}
|
||||
\pause
|
||||
\ifger{Jetzt wollen wir den Betrag jedes Elements:}{Now we want the absolute of every element:}
|
||||
\begin{haskellcode}
|
||||
absList :: [Int] -> [Int]
|
||||
absList [] = []
|
||||
absList [] = []
|
||||
absList (x:xs) = (abs x) : absList xs
|
||||
\end{haskellcode}
|
||||
\pause
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
f :: Int -> Int
|
||||
f x = x + 1
|
||||
\end{haskellcode}
|
||||
\ifger{Aber stellen wir uns vor, dass wir einige Hilfsfunktionen benötigen, die sehr spezifisch ist und eigentlich zur aktuellen Funktion gehört. In C würden wir diese vermutlich top-level deklarieren und \cinline{static} machen.}{But now imagine we need a helper function which is very specific to the current function. In C we would have to define this new helper function at top-level and would probably make it \cinline{static}.}
|
||||
\ifger{Aber stellen wir uns vor, dass wir eine Hilfsfunktion benötigen, die sehr spezifisch ist und eigentlich zur aktuellen Funktion gehört. In C würden wir diese vermutlich top-level deklarieren und \cinline{static} machen.}{But now imagine we need a helper function which is very specific to the current function. In C we would have to define this new helper function at top-level and would probably make it \cinline{static}.}
|
||||
\pause
|
||||
\vspace{\baselineskip}
|
||||
\\
|
||||
|
||||
@@ -7,13 +7,4 @@ head :: [a] -> a
|
||||
\vspace{\baselineskip}
|
||||
\\
|
||||
\pause
|
||||
\ifger{Wir können sogar Funktionen schreiben wie:}{We can also have:}
|
||||
\begin{haskellcode}
|
||||
f :: a -> b
|
||||
\end{haskellcode}
|
||||
\pause
|
||||
\ifger{D.h. was auch immer diese Funktion macht, sie bekommt etwas von einem Typ rein und gibt etwas von einem anderen Typ aus. \hinline{a} und \hinline{b} könnten vom selben Typ sein, müssen aber nicht! D.h. Funktionen dieser Art geben uns häufig mehr Freiheit. Mehr können wir über diese Funktion nicht sagen.}{So, whatever the function does... it gets something of one type and returns something of another type. \hinline{b} \emph{could} be the same type as \hinline{a} here, but it doesn't need to, so functions of this type often give us more freedom! That's all we know about this function.}
|
||||
\vspace{\baselineskip}
|
||||
\\
|
||||
\pause
|
||||
\ifger{Hinweis: wir müssen nicht die Buchstaben \hinline{a} und \hinline{b} nehmen. Sie werden nur häufig für generische Datentypen benutzt.}{Note: you don't have to use \hinline{a} or \hinline{b} here. These letters are just commonly used for generic types.}
|
||||
\ifger{Frage: könnte \hinline{a} eine Funktion sein?}{Question: could \hinline{a} be a function?}
|
||||
10
VL2/content/VL2_polymorphism3.tex
Normal file
10
VL2/content/VL2_polymorphism3.tex
Normal file
@@ -0,0 +1,10 @@
|
||||
\ifger{Wir können sogar Funktionen schreiben wie:}{We can also have:}
|
||||
\begin{haskellcode}
|
||||
f :: a -> b
|
||||
\end{haskellcode}
|
||||
\pause
|
||||
\ifger{D.h. was auch immer diese Funktion macht, sie bekommt etwas von einem Typ rein und gibt etwas von einem anderen Typ aus. \hinline{a} und \hinline{b} könnten vom selben Typ sein, müssen aber nicht! D.h. Funktionen dieser Art geben uns häufig mehr Freiheit. Mehr können wir über diese Funktion nicht sagen.}{So, whatever the function does... it gets something of one type and returns something of another type. \hinline{b} \emph{could} be the same type as \hinline{a} here, but it doesn't need to, so functions of this type often give us more freedom! That's all we know about this function.}
|
||||
\vspace{\baselineskip}
|
||||
\\
|
||||
\pause
|
||||
\ifger{Hinweis: wir müssen nicht die Buchstaben \hinline{a} und \hinline{b} nehmen. Sie werden nur häufig für generische Datentypen benutzt.}{Note: you don't have to use \hinline{a} or \hinline{b} here. These letters are just commonly used for generic types.}
|
||||
@@ -1,6 +1,6 @@
|
||||
\begin{itemize}
|
||||
\item \ifger{was ist der Unterschied zwischen}{what is the difference between} \hinline{let} \ifger{und}{and} \hinline{where}?
|
||||
\item \ifger{was ist der Unterschied zwischen}{what is the difference between} \hinline{foldr} \ifger{und}{and} \hinline{foldl}?
|
||||
\item \ifger{was ist der Unterschied zwischen}{what is the difference between} \hinline{foldr} \ifger{und}{and} \hinline{foldl}? \ifger{Welches davon ist tail bzw. head recursive?}{Which one is tail and which one head recursive?}
|
||||
\item \ifger{was ist der Unterschied zwischen expliziter und impliziter Rekursion? Beispiele?}{what is the difference between explicit and implicit recursion? Give examples}
|
||||
\item \ifger{wie viele Argumente hat eine Haskell Funktion (streng genommen)?}{how many arguments does a haskell function have (strictly speaking)?}
|
||||
\item \ifger{Sind diese Typsignaturen technisch äquivalent?}{Are these type signatures technically equivalent?}
|
||||
|
||||
Reference in New Issue
Block a user