This is a summary of the course ``Algebra des Programmierens'' taught by Prof.\ Dr.\ Stefan Milius in the winter term 2023/2024 at the FAU~\footnote{Friedrich-Alexander-Universität Erlangen-Nürnberg}.
The course is based on~\cite{poll1999algebra} with~\cite{adamek1990abstract} as a reference for category theory.
Goal of the course is to develop a mathematical theory for semantics of data types and their accompanying proof principles. The chosen environment is the field of category theory.
A function $f : X \rightarrow Y$ is a mapping from the set $X$ (the domain of $f$) to the set $Y$ (the codomain of $f$).
More concretely $f$ is a relation $f \subseteq X \times Y$ which is
\begin{itemize}
\item\emph{left-total}, i.e.\ for all $x \in X$ exists some $y \in Y$ such that $(x,y)\in f$;
\item\emph{right-unique}, i.e.\ any $(x,y),(x,y')\in f$ imply $y = y'$.
\end{itemize}
Often, one is also interested in the symmetrical properties, a function is called
\begin{itemize}
\item\emph{injective} or \emph{left-unique} if for every $x,x' \in X$ the implication $f(x)= f(x')\rightarrow x = x'$ holds;
\item\emph{surjective} or \emph{right-total} if for every $y \in Y$ there exists an $x \in X$ such that $f(x)= y$;
\item\emph{bijective} if it is injective and surjective.
\end{itemize}
\begin{example}
\begin{enumerate}
\item The identity function $id_A : A \rightarrow A$, $id_A(x)= x$
\item The constant function $b! : A \rightarrow B$ for $b \in B$ defined by $b!(x)= b$
\item The inclusion function $i_A : A \rightarrow B$ for $A \subseteq B$ defined by $i_A(x)= x$
\item Constants $b : 1\rightarrow B$, where $1 :={*}$. The function $b$ is in bijection with the set $B$.
\item Composition of function $f : A \rightarrow B, g : B \rightarrow C$ called $g \circ f : A \rightarrow C$ defined by $(g \circ f)(x)= g(f(x))$.
\item The empty function $¡ : \emptyset\rightarrow B$
\item The singleton function $! : A \rightarrow1$
\end{enumerate}
\end{example}
\subsection{Data Types}
Programs work with data that should ideally be organized in a useful manner.
A useful representation for data in functional programming is by means of \emph{algebraic data types}.
Some basic data types (written in Haskell notation) are
\begin{minted}{haskell}
data Bool = True | False
data Nat = Zero | Succ Nat
\end{minted}
These data types are declared by means of constructors, yielding concrete descriptions how inhabitants of these types are created.
\emph{Parametric data types} are additionally parametrized by another data type, e.g.\
\begin{minted}{haskell}
data Maybe a = Nothing | Just a
data Either a b = Left a | Right b
data List a = Nil | Cons a (List a)
\end{minted}
Such data types (parametric or non-parametric) usually come with a principle for defining functions called recursion and in richer type systems (e.g.\ in a dependently typed setting) with a principle for proving facts about recursive functions called induction.
Equivalently, every function defined by recursion can be defined via a \emph{fold}-function which satisfies an identity and fusion law, which replace the induction principle. Let us now consider two examples of data types and illustrate this.
\subsubsection{Natural Numbers}
The type of natural numbers comes with a fold function $foldn : C \rightarrow(Nat \rightarrow C)\rightarrow Nat \rightarrow C$ for every $C$, defined by
\begin{alignat*}{2}
& foldn\;c\;h\;zero && = c \\
& foldn\;c\;h\;(suc\;n) && = h\;(foldn\;c\;h\;n)
\end{alignat*}
\begin{example} Let us now consider some functions defined in terms of $foldn$.
\begin{itemize}
\item$iszero : Nat \rightarrow Bool$ is defined by
\[iszero = foldn\;true\;false!\]
\item$plus : Nat \rightarrow Nat \rightarrow Nat$ is defined by