Whatever the function does... it has something of one type and returns something of another type (it could be the same type, but doesn't need to). That's all we know.
Now you know how a regular function looks like, e.g:
\begin{haskellcode}
f :: Int -> Int
f x = x + 1
\end{haskellcode}
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 \code{static}.
\pause
\vspace{\baselineskip}
\\
Haskell allows us to \textbf{inline} functions in a few more ways, e.g.:
\begin{itemize}[<+->]
\item with \code{where}
\item with \code{let...in}
\item anonymously (lambda abstraction)
\end{itemize}
\onslide<+->
A lot of Haskellers really dislike if you put non-generic functions at the top level. So you can still have atomic pieces, but inline the parts which are very specific to the current function.
These look almost the same, but they are different constructs. \code{where} is bound to the pattern matching \code{f x =} and may also have access to parts of a function that are not syntactically expressions, e.g.:
While that is not possible with \code{let}, which is an actual expression and can be used whenever expressions are allowed (e.g. inside \emph{Monads}, we'll know more about these in a few weeks).
This is what actually makes haskell such a fine functional language. You might have noticed that I tried hard to not show type signatures of functions that have more than one argument. Well, that's because we have to dig a little deeper to explain what comes next:
\pause
\begin{haskellcode}
addInt :: Int -> Int -> Int
addInt x y = x + y
\end{haskellcode}
\pause
So, what is happening here? You probably expected something like:
Currying is actually a mathematical thing and is the technique of translating the evaluation of a function that takes multiple arguments (or a tuple) into evaluating a sequence of functions, each with a single argument.
$z = f(x, y)$ is 3-dimensional. 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$.
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:
\begin{haskellcode}
f :: Int -> Int -> Int
f :: Int -> (Int -> Int)
\end{haskellcode}
On the other hand function application is \emph{left}-associative, so \code{f 3 2} is just a shorthand of \code{(f 3) 2}. Makes sense?
What does that mean for us? It's not just fun stuff or aesthetic. It allows us to do \textbf{partial application}. That means we do not have to give a function all arguments. If we pass an "insufficient" number of arguments it will just give us a new function! Here:
\pause
\begin{haskellcode}
addInt :: Int -> Int -> Int
addInt x y = x + y
addTwo :: Int -> Int
addTwo = addInt 2
\end{haskellcode}
You probably noticed that we did not write \code{addTwo x = ...}, but why would we? We gave \code{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.
So why did we just bother so long with explaining currying? It's because it's very important for function composition. Which again is also one of the fundamental concepts of functional programming.
\vspace{\baselineskip}
\\
From maths we already know that:\\
$(g \circ f)(x)= g(f(x))$
\vspace{\baselineskip}
\\
\pause
And that's basically it. We do the same in haskell, it looks like this:
\begin{haskellcode}
composedFunction x = (f . g) x
-- same as above... everything on the right side of $
-- is evaluated first
composedFunction x = f . g $ x
-- and same again, remember that 'f x ='
-- is just syntax sugar
-- omitting the x here is also called eta reduction
\textbf{Exercise:} Find the answer! 5 minutes time, remember the \emph{cons} operator \code{(:)}, pattern matching on lists and ofc recursion! Start with the case of an empty list.
All those 3 functions look almost the same. Since haskell is about abstraction, we would never really write any of those like that. Instead, we will write a function that generalizes all 3.
\vspace{\baselineskip}
\\
\pause
I'll give you the type signature, can you guess how the implementation looks like?
\begin{haskellcode}
map :: (a -> b) -> [a] -> [b]
\end{haskellcode}
Solution?
\pause
\begin{haskellcode}
map :: (a -> b) -> [a] -> [b]
map f [] = []
map f (x:xs) = f x : map f xs
\end{haskellcode}
So we don't really know what the function \code{f} does, but we know that it converts one element of the list to something else. We \emph{map} a function over a list! Hence the name.
Cool, right? So now we have abstracted out the \textbf{recursion pattern} that is all the same for those 3 functions. \code{map} is actually part of the standard library (called \emph{Prelude}).