Compare commits
40 Commits
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 | ||
|
f335b3a522 | ||
|
1975e27e5c | ||
|
3cfdec16ed | ||
|
c504fba841 | ||
|
913900a9e8 | ||
|
91330daea8 | ||
|
5acabb296f | ||
|
198ccedcf5 | ||
|
ab7c101b4b | ||
|
4f67c48b6f | ||
|
d9750e6b34 | ||
|
5b4be12e0b | ||
|
9dc7adaaf3 | ||
|
1838c3276f | ||
|
02a33a44fe | ||
|
361af10451 | ||
|
e315e78b39 | ||
|
efc0f586ed |
@ -90,24 +90,6 @@
|
||||
|
||||
\slide{./content/VL1_pairs.tex}
|
||||
|
||||
\subsection{\ifger{Algebraische Datentypen}{Algebraic Data Types}}
|
||||
|
||||
\slidetoc
|
||||
|
||||
\slide{./content/VL1_ADT1.tex}
|
||||
\slide{./content/VL1_ADT2.tex}[ (cnt.)]
|
||||
\slide{./content/VL1_ADT3.tex}[ (cnt.)]
|
||||
\slide{./content/VL1_ADT4.tex}[ (cnt.)]
|
||||
|
||||
\subsubsection{Trees}
|
||||
|
||||
\slide{./content/VL1_ADT5.tex}
|
||||
\slide{./content/VL1_ADT6.tex}[ (cnt.)]
|
||||
|
||||
\subsubsection{ADTs \ifger{allgemein}{generalized}}
|
||||
|
||||
\slide{./content/VL1_ADT7.tex}
|
||||
|
||||
\section{Résumé}
|
||||
|
||||
\slidetoc
|
||||
|
@ -1,20 +0,0 @@
|
||||
\ifger{Natürlich können wir auch unsere eigenen Datentypen definieren. Ein sehr häufiger Typ ist die \emph{Enumeration}. Z.b. können wir den Wochentag definieren als:}{Of course we can also define our own data types in haskell. One very common type is the \emph{enumeration}. For example, we could define a data type for the Week:}
|
||||
\begin{haskellcode}
|
||||
data WeekDay = Monday
|
||||
| Tuesday
|
||||
| Thursday
|
||||
| Wednesday
|
||||
| Friday
|
||||
| Saturday
|
||||
| Sunday
|
||||
\end{haskellcode}
|
||||
\ifger{Dies erzeugt den neuen Datentyp}{This creates the new data type} \hinline{WeekDay} \ifger{mit}{with} 7 \emph{\ifger{Konstruktoren}{constructors}}. \ifger{Das bedeutet, dass}{That means} \hinline{Monday}, \hinline{Tuesday} etc. \ifger{alles Werte vom Typ}{are all values of the type} \hinline{WeekDay}\ifger{ sind.}{.}
|
||||
\pause
|
||||
\\
|
||||
\ifger{Jetzt können wir auch eine ganze Woche definieren mittels einer Liste:}{We could now define a whole week, by creating a list:}
|
||||
\pause
|
||||
\begin{haskellcode}
|
||||
week :: [WeekDay]
|
||||
week = [Monday, Tuesday, Thursday, Wednesday
|
||||
, Friday, Saturday, Sunday]
|
||||
\end{haskellcode}
|
@ -1,7 +0,0 @@
|
||||
\ifger{Und auch auf unserem \hinline{WeekDay} Typ können wir \emph{pattern matchen}. Wir wollen z.B. herausfinden, ob ein gegebener Tag ein Montag ist:}{And we can again \emph{pattern match} on our \hinline{WeekDay} type. Let's find out if a given day is a Monday:}
|
||||
\pause
|
||||
\begin{haskellcode}
|
||||
isMonday :: WeekDay -> Bool
|
||||
isMonday Monday = True
|
||||
isMonday x = False
|
||||
\end{haskellcode}
|
@ -1,14 +0,0 @@
|
||||
\ifger{Wir können natürlich auch mehr als nur Enumerationen. Wie wäre es mit Fehlerbehandlung? Z.B. wollen wir eine Funktion, die einen Int zurückgibt, aber falls etwas schief gelaufen ist wollen wir nicht einfach nur eine 0 oder einen magischen Wert, sondern eine richtige Fehlernachricht zurückgeben:}{But we can do more than enumerations. How about we do some error handling? Let's say we want a function to return an \hinline{Int}, but in case something went horribly wrong, we don't just want to return a 0 or some magic number, but a proper error message. Here we go:}
|
||||
\pause
|
||||
\begin{haskellcode}
|
||||
data MaybeInt = NoError Int
|
||||
| Error String
|
||||
\end{haskellcode}
|
||||
\pause
|
||||
\ifger{D.h. Konstruktoren sind auch gewöhnliche \emph{Funktionen}! Und sie können Argumente haben, genau wie Funktionen. Hier ist die Typsignatur:}{So constructors are just \emph{functions}! And they can have arguments, just like functions. Let's check their types:}
|
||||
\begin{haskellcode}
|
||||
> :t NoError
|
||||
NoError :: Int -> MaybeInt
|
||||
> :t Error
|
||||
Error :: String -> MaybeInt
|
||||
\end{haskellcode}
|
@ -1,15 +0,0 @@
|
||||
\ifger{Und jetzt können wir Sicherheitsabfragen machen:}{And now we can do sanity checks:}
|
||||
\begin{haskellcode}
|
||||
calcSomething :: Int -> MaybeInt
|
||||
calcSomething x
|
||||
| x < 100 = NoError (x * 5)
|
||||
| otherwise = Error "Int out of range!"
|
||||
\end{haskellcode}
|
||||
\pause
|
||||
\ifger{Und darauf \emph{pattern matchen}}{And pattern match on it as well}:
|
||||
\begin{haskellcode}
|
||||
addIntToList :: MaybeInt -> [Int]
|
||||
addIntToList (NoError x) = [x]
|
||||
addIntToList (Error str) = []
|
||||
\end{haskellcode}
|
||||
\ifger{D.h. wenn wir hier einen Error bekommen, geben wir einfach eine leere Liste zurück. Ansonsten geben wir die Liste mit dem \hinline{Int} als einziges Element zurück.}{So if we got an error, we just return an empty list, otherwise we return a list with the \hinline{Int} as its only element.}
|
@ -1,23 +0,0 @@
|
||||
\ifger{Jetzt wollen wir etwas komplexere ADTs definieren. Z.b. einen Tree:}{Let's define something more complex. How about a tree?}
|
||||
\pause
|
||||
\begin{haskellcode}
|
||||
data Tree = Leaf Char
|
||||
| Node Tree Int Tree
|
||||
\end{haskellcode}
|
||||
\ifger{Verwirrt? Schauen wir genauer hin.}{Uh... that looks mean. Let's examine this.}\\
|
||||
\pause
|
||||
\ifger{Wir haben}{We have}:
|
||||
\begin{itemizep}
|
||||
\item \ifger{den Datentyp \hinline{Tree} definiert}{defined a data type \hinline{Tree}}
|
||||
\item \ifger{einen Konstruktor \hinline{Leaf} vom Typ \hinline{Tree} mit einem Argument vom Typ \hinline{Char}}{a constructor \hinline{Leaf} of type \hinline{Tree} with one arguments of type \hinline{Char}}
|
||||
\item \ifger{einen Konstruktor \hinline{Node} vom Typ \hinline{Tree} mit 3 Argumenten}{a constructor \hinline{Node} of type \hinline{Tree} with 3 arguments}
|
||||
\begin{itemizep}
|
||||
\item \hinline{Tree}
|
||||
\item \hinline{Int}
|
||||
\item \hinline{Tree}
|
||||
\end{itemizep}
|
||||
\end{itemizep}
|
||||
\slidep
|
||||
\ifger{Das bedeutet: ein \hinline{Tree} kann entweder ein \hinline{Leaf} oder eine interne \hinline{Node} sein mit 2 Subtrees. Wollen wir einen \hinline{Leaf} erzeugen, müssen wir dem Konstruktor einen \hinline{Char} übergeben. Wollen wir eine \hinline{Node} bauen, müssen wir 3 Argumente in Reihenfolge übergeben: ein weiterer \hinline{Tree}, ein \hinline{Int} und noch ein \hinline{Tree}.}{That means: a \hinline{Tree} can either be a \hinline{Leaf} or an internal \hinline{Node} with two sub-trees. If we want to create a \hinline{Leaf}, we have to pass the constructor a \hinline{Char}. If we want to create a \hinline{Node}, we have to pass 3 arguments, in order: another \hinline{Tree}, an \hinline{Int} and yet another \hinline{Tree}.}\\
|
||||
\ifger{D.h. wir können Informationen sowohl in den leafs (\hinline{Char}) als auch in den internen nodes (\hinline{Int}) speichern. Dies ist nur ein Beispiel.}{So we can save information in the leafs (\hinline{Char}) and in the internal nodes (\hinline{Int}).\\
|
||||
This is just an example. There are endless more ways of trees.}
|
@ -1,13 +0,0 @@
|
||||
\ifger{Wir bauen unseren Tree:}{Let's build our tree:}
|
||||
\begin{haskellcode}
|
||||
tree :: Tree
|
||||
tree = Node
|
||||
(Leaf 'x')
|
||||
1
|
||||
(Node
|
||||
(Leaf 'y')
|
||||
2
|
||||
(Leaf 'z')
|
||||
)
|
||||
\end{haskellcode}
|
||||
\ifger{Siehe Tafel...}{See board...}
|
@ -1,7 +0,0 @@
|
||||
\ifger{D.h. wenn wir verallgemeinern müssten, hat ein algebraischer Datentyp einen oder mehr \textbf{Konstruktoren}, von denen jeder null oder mehr \textbf{Argumente} hat. Z.B.:}{So if we want to generalize it, an algebraic data type has one or more \textbf{constructors}, and each of them can have zero or more \textbf{arguments}. E.g.:}
|
||||
\begin{haskellcode}
|
||||
data AlgDataType = Constr1 Type11 Type12
|
||||
| Constr2 Type21
|
||||
| Constr3 Type31 Type32 Type33
|
||||
| Constr4
|
||||
\end{haskellcode}
|
@ -10,9 +10,8 @@
|
||||
\end{itemize}
|
||||
\ifger{Ist dies eine \emph{total} oder eine \emph{partial} Funktion? Wie müsste man sie eventuell umschreiben?}{Is this a total or a partial function? Would you extend it? How?}
|
||||
\begin{haskellcode}
|
||||
data IntOrDouble = MkDouble Double
|
||||
| MkInt Int
|
||||
|
||||
f :: Int -> IntOrDouble
|
||||
f 0 = 0.5
|
||||
even :: Int -> Bool
|
||||
f 0 = True
|
||||
f 2 = True
|
||||
f 4 = True
|
||||
\end{haskellcode}
|
@ -3,5 +3,4 @@
|
||||
\item \ifger{wie schreibe ich Haskell Funktionen?}{how you write haskell functions?}
|
||||
\item \ifger{wie gehe ich mit Listen und Tuplen um?}{how you handle lists and pairs?}
|
||||
\item \ifger{wie funktioniert pattern matching?}{how you do pattern matching?}
|
||||
\item \ifger{wie man seine eigenen Datentypen definiert}{how you create your own data types}
|
||||
\end{itemize}
|
@ -2,19 +2,4 @@
|
||||
\vspace{\baselineskip}
|
||||
\\
|
||||
\pause
|
||||
\ifger{Noch besser sogar! Haskell erlaubt standardmäßig Polymorphie, ohne komplizierte APIs oder Spracherweiterungen.}{Even better! Haskell supports polymorphism for both data types and functions, out of the box without any language extensions.}\\
|
||||
\ifger{Wir beginnen mit einem polymorphen Datentyp:}{Let's start with a polymorphic data type:}
|
||||
\begin{haskellcode}
|
||||
data List t = Empty | Cons t (List t)
|
||||
\end{haskellcode}
|
||||
\ifger{Wir haben soeben unsere eigene singly-linked Liste implementiert. Für jeden Typ! Ein paar Beispiele:}{So we just implemented our own singly-linked List. For any type! Let's use it:}
|
||||
\pause
|
||||
\begin{haskellcode}
|
||||
intList :: List Int
|
||||
intList = Cons 3 (Cons 5 (Cons 2 Empty))
|
||||
|
||||
charList :: List Char
|
||||
charList = Cons 'x' (Cons 'y' (Cons 'z' Empty))
|
||||
|
||||
-- whatever you can imagine goes here
|
||||
\end{haskellcode}
|
||||
\ifger{Noch besser sogar! Haskell erlaubt standardmäßig Polymorphie, ohne komplizierte APIs oder Spracherweiterungen.}{Even better! Haskell supports polymorphism for both data types and functions, out of the box without any language extensions.}
|
@ -1,12 +1,10 @@
|
||||
\ifger{Und jetzt können wir sie nutzen:}{And now we are going to write functions to use it:}
|
||||
\ifger{Beginnen wir mit einer polymorphen Funktion, die wir bereits kennen:}{Let's start with a polymorphic function that you already know:}
|
||||
\begin{haskellcode}
|
||||
isListEmpty :: List t -> Bool
|
||||
isListEmpty Emtpy = True
|
||||
isListEmpty x = False
|
||||
head :: [a] -> a
|
||||
\end{haskellcode}
|
||||
\pause
|
||||
\ifger{Wir können sogar Funktionen schreiben wie:}{We can also have:}
|
||||
\begin{haskellcode}
|
||||
f :: a -> b
|
||||
\end{haskellcode}
|
||||
\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.}
|
||||
\ifger{Also, }{So} \hinline{head} \ifger{nimmt eine Liste irgendeines (unbekannten) Typs und gibt uns ein einziges Elements dieser Liste zurück, mit \emph{exakt} demselben Typ.}{takes a list of any type and returns an element which must have the \emph{exact same} type of that list.}
|
||||
\vspace{\baselineskip}
|
||||
\\
|
||||
\pause
|
||||
\ifger{Frage: könnte \hinline{a} eine Funktion sein?}{Question: could \hinline{a} be a function?}
|
@ -1,8 +1,10 @@
|
||||
\ifger{Erinnern wir uns an die Funktion \hinline{head}. Wir können auf jeder Art von Liste mit ihr operieren. Die Typsignatur:}{Similarly, remember the function \hinline{head} which gives us the first element of a list? The type signature actually looks like this:}
|
||||
\ifger{Wir können sogar Funktionen schreiben wie:}{We can also have:}
|
||||
\begin{haskellcode}
|
||||
head :: [a] -> a
|
||||
f :: a -> b
|
||||
\end{haskellcode}
|
||||
\ifger{Macht Sinn?}{Makes sense?}
|
||||
\vspace{\baselineskip}\\
|
||||
\pause
|
||||
\ifger{Frage: könnte \hinline{a} eine Funktion sein?}{Question: could \hinline{a} be a function?}
|
||||
\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.}
|
@ -2,5 +2,4 @@
|
||||
\item \ifger{Was ist Haskell? Was sind die 3 fundamentalen Konzepte hinter Haskell?}{What is haskell? What are the 3 fundamental concepts behind it?}
|
||||
\item \ifger{Wie funktioniert pattern matching?}{How do you do pattern matching?}
|
||||
\item \ifger{Was ist der Unterschied zwischen einer Liste und einem Tuple? Wie erzeugt man sie?}{What is the difference between lists and tuples? How do you construct them?}
|
||||
\item \ifger{Wie definieren wir unsere eigenen Datentypen?}{How do you define your own data types?}
|
||||
\end{itemize}
|
@ -1,5 +1,5 @@
|
||||
\begin{itemize}
|
||||
\item \ifger{wie man polymorphe Funktionen und Datentypen schreibt}{how to write polymorphic data types and functions}
|
||||
\item \ifger{wie man polymorphe Funktionen schreibt}{how to write polymorphic functions}
|
||||
\item \ifger{wie man \emph{inline} Funktionen schreibt}{how you inline functions}
|
||||
\item \ifger{was Currying ist und wieso wir es in Haskell benötigen}{what currying is and why we need it in haskell}
|
||||
\item \ifger{wie man Funktionen verkettet}{how you compose functions}
|
||||
|
Loading…
Reference in New Issue
Block a user