Add algebraic data types section
This commit is contained in:
parent
39e04a49aa
commit
ff90ab5a8a
125
VL1.tex
125
VL1.tex
@ -436,6 +436,131 @@ Now let's say we want all numbers between 50 and 100 that have the remainder 0 w
|
||||
\code{x <- [50..100]} is the binding, while \code{mod x 12 == 0} is the predicate, separated by a comma. We can have multiple predicates.
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[fragile]
|
||||
\frametitle{Algebraic Data Types}
|
||||
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:
|
||||
\setHaskellCodeStyle
|
||||
\begin{lstlisting}
|
||||
data WeekDay = Monday
|
||||
| Tuesday
|
||||
| Thursday
|
||||
| Wednsday
|
||||
| Friday
|
||||
| Saturday
|
||||
| Sunday
|
||||
\end{lstlisting}
|
||||
This declares the new data type \code{WeekDay} with 7 \emph{constructors}. That means \code{Monday}, \code{Tuesday} etc. are all values of the type \code{WeekDay}.
|
||||
\pause
|
||||
\\
|
||||
We could now define a whole week, by creating a list:
|
||||
\pause
|
||||
\setHaskellCodeStyle
|
||||
\begin{lstlisting}
|
||||
week :: [WeekDay]
|
||||
week = [Monday, Tuesday, Thursday, Wednsday
|
||||
, Friday, Saturday, Sunday]
|
||||
\end{lstlisting}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[fragile]
|
||||
\frametitle{Algebraic Data Types (ctn.)}
|
||||
And we can again \emph{pattern match} on our \code{WeekDay} type. Let's find out if a given day is a monday:
|
||||
\pause
|
||||
\setHaskellCodeStyle
|
||||
\begin{lstlisting}
|
||||
isMonday :: WeekDay -> Bool
|
||||
isMonday Monday = True
|
||||
isMonday x = False
|
||||
\end{lstlisting}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[fragile]
|
||||
\frametitle{Algebraic Data Types (ctn.)}
|
||||
But we can do more than enumerations. How about we do some error handling? Let's say we want a function to return an \code{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
|
||||
\setHaskellCodeStyle
|
||||
\begin{lstlisting}
|
||||
data MaybeInt = NoError Int
|
||||
| Error String
|
||||
\end{lstlisting}
|
||||
\pause
|
||||
And now we can do sanity checks:
|
||||
\pause
|
||||
\setHaskellCodeStyle
|
||||
\begin{lstlisting}
|
||||
calcSomething :: Int -> MaybeInt
|
||||
calcSomething x
|
||||
| x < 100 = NoError (x * 5)
|
||||
| otherwise = Error "Int out of range!"
|
||||
\end{lstlisting}
|
||||
\pause
|
||||
So constructors are just \emph{functions}! And they can have arguments, just like functions. Let's check their types:
|
||||
\setHaskellCodeStyle
|
||||
\begin{lstlisting}
|
||||
> :t NoError
|
||||
NoError :: Int -> MaybeInt
|
||||
> :t Error
|
||||
Error :: String -> MaybeInt
|
||||
\end{lstlisting}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[fragile]
|
||||
\frametitle{Algebraic Data Types (ctn.)}
|
||||
Let's define something more complex. How about a tree?
|
||||
\pause
|
||||
\setHaskellCodeStyle
|
||||
\begin{lstlisting}
|
||||
data Tree = Leaf Char
|
||||
| Node Tree Int Tree
|
||||
\end{lstlisting}
|
||||
Uh... that looks mean. Let's examine this.\\
|
||||
\pause
|
||||
We have:
|
||||
\begin{itemize}[<+->]
|
||||
\item defined a data type \code{Tree}
|
||||
\item a constructor \code{Leaf} of type \code{Tree} with one arguments of type \code{Char}
|
||||
\item a constructor \code{Node} of type \code{Tree} with 3 arguments
|
||||
\begin{itemize}[<+->]
|
||||
\item \code{Tree}
|
||||
\item \code{Int}
|
||||
\item \code{Tree}
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
\onslide<+->
|
||||
That means: a \code{Tree} can either be a \code{Leaf} or an internal \code{Node} with two sub-trees. If we want to create a \code{Leaf}, we have to pass the constructor a \code{Char}. If we want to create a \code{Node}, we have to pass 3 arguments, in order: another \code{Tree}, an \code{Int} and yet another \code{Tree}.\\
|
||||
So we can save information in the leafs (\code{Char}) and in the internal nodes (\code{Int}).\\
|
||||
This is just an example. There are endless more ways of trees.
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[fragile]
|
||||
\frametitle{Algebraic Data Types (ctn.)}
|
||||
Let's build our tree:
|
||||
\setHaskellCodeStyle
|
||||
\begin{lstlisting}
|
||||
tree :: Tree
|
||||
tree = Node
|
||||
(Leaf 'x')
|
||||
1
|
||||
(Node
|
||||
(Leaf 'y')
|
||||
2
|
||||
(Leaf 'z')
|
||||
)
|
||||
\end{lstlisting}
|
||||
See board...
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[fragile]
|
||||
\frametitle{Algebraic Data Types (ctn.)}
|
||||
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 arguments. E.g.:
|
||||
\setHaskellCodeStyle
|
||||
\begin{lstlisting}
|
||||
data AlgDataType = Constr1 Type11 Type12
|
||||
| Constr2 Type21
|
||||
| Constr3 Type31 Type32 Type33
|
||||
| Constr4
|
||||
\end{lstlisting}
|
||||
\end{frame}
|
||||
\begin{frame}
|
||||
\frametitle{Toolchain}
|
||||
You need:
|
||||
|
Loading…
Reference in New Issue
Block a user