---
# System prepended metadata

title: Structure Preserving Maps

---

# Structure Preserving Maps

# Universal Algebra

# Algebraic Data Types

(not in final form)

Part 2 of a [short course on monads](https://hackmd.io/@alexhkurz/H1OxumxRP).


In the previous lecture, we discussed monoids as a paradigmatic example of an algebraic structure. The importance of paradigmatic examples is that they can be generalised in *different* ways. One important way to generalise monoids is to say that a monoid is made from **operations and equations**: Operations for neutral element (empty word) and mutiplication (concatenation) and equations for identity and associativity.

To capture more diverse structures, we should generalise to other kind of operations and equations. The area of mathematics that studies mathematical objects defined by operations and equations is known as **Universal Algebra**, or also General Algebra. The objects of study are called algebras.

An important application of algebra to programming are **algebraic data types**. We have seen examples in the previous lecture and will see more in this one.

In the lecture we went trough the Example, the Axioms, some More Examples and then discussed the program [`algebraic-data-types`](https://repl.it/@alexhkurz/algebraic-data-types-1). At the beginning of the next lecture I explained the notion of termalgebra and that it makes mathematically precise on what domain we do induction when we program with algebraic data types. Finally, I briefly touched upon the remainig points made in these notes. 

Programs: [`induction`](https://repl.it/@alexhkurz/induction#main.hs), [`algebraic-data-types`](https://repl.it/@alexhkurz/algebraic-data-types-1), [`magma`](https://repl.it/@alexhkurz/magma#main.hs).


## Example

The clock is a function


![](https://i.imgur.com/9HAvLD1.png)

(We make various assumptions here such as that time can be measured in discrete units, stretches from negative infinity to infinity.)

A clock that is neither fast nor slow has the additional property of preserving  the structure of time. We can model this mathematically, by equipping $\mathbb Z$ with the structure $(\mathbb Z, 0, +)$ of addition. Similarly, we introduce the notation of  $\mathbb Z/12\mathbb Z$ for the set $\{0,\ldots 11\}$ with addition as on the clock.

That the clock is preserving the structure of addition can now be expressed by saying that diagram

![](https://i.imgur.com/1HTkvHw.png =500x)


commutes. Algebraically, this is just an equation
$$clock(x+1) = clock(x)+1$$

where $+1$ on the left refers to integer addition and $+1$ on the right refers to addition modulo 12. Moreover, it seems reasonable to require
$$clock(0) = 0$$

Let us call, just for the purposes of this example, a function that satisfies these equations a *proper clock*. 

If we put these equations into words we can say that "one unit of time advances the clock by one unit". So the following should be more or less obvious, but one can also prove it by induction.

**Exercise:** There infinitely many functions $\mathbb Z\to\mathbb Z/12$, but there is only one function satisfying the equations above. [^plusone]

[^plusone]: Why is $x\mapsto 2x$ not a proper clock? Which function corresponds to the clock that run out of battery? 

In many programming and mathematical problems, to determine the relevant structure can be a big step towards a solution. Even in the example of the clock, we can think of different structure that we may want to preserve. 

For example, both $\mathbb Z$ and $\mathbb Z/12\mathbb Z$ are monoids under addition. So we could ask, in addition to $clock(0)=0$, for the following diagram to commute.

![](https://i.imgur.com/iObpCVM.png =500x)

Algebraically, that would be written as
$$clock(x+y) = clock(x)+clock(y)$$

The purpose of the exercise is to show that this defines a more permissive notion of structure preserving map. But let us first pause and recognise that we just met what is known as a monoid homomorphism. [^homomorphism]

[^homomorphism]: Is constructed from two Greek words meaning "similar form".

**Definition:** Let $(M,e,\cdot)$ and $(M',e',*)$ be two monoids. Then $f:M\to M'$ is a **monoid homomorphism** if
\begin{gather}
f(e)=f(e')\\
f(x\cdot y)=f(x)*f(y)
\end{gather}



**Exercise:** Find the 5 different monoid  homomorphisms $(\mathbb Z, 0, +)\to(\mathbb Z/12\mathbb Z, 0, +)$. [^overloading]

[^overloading]: We use the same symbols $0$ and $+$ for two different operations. Both in mathematics and in programming is this kind of [overloading](https://en.wikipedia.org/wiki/Function_overloading) widely used.


We have introduced monoids as a paradigmatic example of an algebra. The importance of paradigmatic example is that they can be generalised in various different ways. A monoid is made from **operations and equations**: Operations for neutral element (empty word) and mutiplication (concatenation) and equations for identity and associativity.

The area of mathematics that studies mathematical objects defined by operations and equations is known as **Universal Algebra**, or also General Algebra. The objects of study are then just called algebras. This is what we will look at next.

## Axioms: Universal Algebra

(essential)

The purpose of this section is to generalise the previous example to algebraic structures defined by arbitrary operations.

First, let us go back to automata-as-algebras, the introductory example of the first lecture. As we have seen, we can think of the alphabet $\Sigma$ as a set of unary operation symbols. An automaton interprets each input symbol as a function $Q\to Q$. In other words, automata can be seen as algebras of unary operations. We now generalise this to operations which can take any number of arguments.

**Definition:** A **signature** is a set $\Sigma$ of operation symbols together with a function $\sf arity:\Sigma\to\mathbb N$.

**Example:** The signature of 
- monoids is $\Sigma = \{e,\cdot\}$ and ${\sf arity}(e)=0$ and ${\sf arity}(\cdot)=2$. 
- lists is $$\Sigma = \{\tt Nil\} \cup \{{\tt Cons\ x} \mid {\tt x} \in \tt a\}$$  

    where $\{\tt Nil\}$ is a constant (arity $0$) and the ${\tt Cons\ x}$  are unary (arity $1$). 

**Remark:** Once we have a signature we can form **terms** from operation symbols and variables. 

**Example:** In the signature of 
- monoids we have terms such as $e\cdot x$ and $x\cdot(y\cdot z)$.
- lists terms are lists.

**Remark:** An **equation** is a pair of terms. 

**Definition:** An **algebra** for a  signature $\Sigma$, or a $\Sigma$-algebra, consists of a set $A$ together with an $n$-ary function (=operation) $A^n\to A$ for each $n$-ary operation symbol of $\Sigma$.

We will see many examples of algebras and structure preserving maps (homomorphisms) in the next section. But first another definition.

**Definition:** Let $\Sigma$ be a signature, $A$ and $B$ two algebras and $f:A\to B$ a function between  between their underlying sets. $f$ is called a **homomorphism**, if for all operations $\sigma$ of arity $n$, we have
$$f(\sigma^A(x_1,\dots x_n)=\sigma^B(f(x_1),\ldots f(x_n))$$

where $\sigma^A$ is the interpretation of $\sigma$ on $A$ and $\sigma^B$ is the interpretation of $\sigma$ on $B$.

**Definition:** $f:A\to B$ is an **isomorphism** if $f$ has an inverse, that is, if there is a homomorphism $g:B\to A$ such that $g\circ f= id$ and $f\circ g=id$.

**Remark:** $f$ is an isomorphism iff $f$ is a bijective homomorphism.

**Remark on many-sorted universal algebra:** For programming applications of universal algebra we want "heterogeneous" or "many-sorted" universal algebra. Indeed, we need algebras that do not have only on "carrier" $A$ but a family $(A_1, A_2,\ldots)$ of carrier sets (or sorts or types). For example, the signature of the length function involves two sorts (types) and the signature of the member function three:

```haskell
len :: List a -> Integer
member :: a -> List a -> Bool
```

Some mathematics texts go the extra mile and extend universal algebra to this more general setting. But all the maths we need can be more easily explained in the one-sorted setting. As a rule of thumb, all results extend to the many-sorted setting, so we are free to apply them to programming with many types. 

## More Examples: Induction

(essential)

The examples of this section explore the following important ideas.  

- The notion of free monoid generalises to algebras for arbitray signatures.
- Free algebras come with a principle of induction that can be used for reasoning and computation.
- Free algebras are unique up to isomorphism.

Again, all of our inductive definitions are implemented in Haskell for you to experiment with in [`induction`](https://repl.it/@alexhkurz/induction#main.hs).

### Natural Numbers via Zero and Successor

Choose the signature $\Sigma = \{\rm O, S\}$ with $\rm arity(O)=0$ and ${\rm arity(S)=1}$, that is, $\rm O$ is a constant and S is a unary operation symbol.

The so-called $\Sigma$-*termalgebra*, or *intial algebra* (see next section for more on termalgebras, initial algebras and free algebras) consists of all terms one can form from the operations of the signature: $\rm O$, $\rm SO$, $\rm SSO$, etc. The operation $\rm S$ takes a term $\rm S\ldots O$ to $\rm SS\ldots O$. In Haskell, this intial algebra can be defined as 

```haskell
data NN = O | S NN
```

**Maths Exercise:** Show that the natural numbers $\mathbb N$ with 0 and $+1$ are isomorphic to the $\Sigma$-termalgebra.

Answer. [^initialSO]

[^initialSO]: The $\Sigma$-termalgebra has elements $\rm O$, $\rm SO$, $\rm SSO$, etc. Define a function from $\mathbb N$ to the termalgebra by induction: $f(0) = \rm O$ and $f(n+1)={\rm S} f(n)$. This function is bijective, hence an isomorphism.

**Induction on natural numbers:** The principle of definition by induction goes as follows. For any $i\in\mathbb N$ and $s:\mathbb N \to \mathbb N$ there is a unique funtion $f:\mathbb N \to \mathbb N$
\begin{align}
f(0) & = i \\
f(n+1) & = s(f(n))
\end{align}

**Maths Exercise:** More generally, for any $\Sigma$-algebra $(A,\rm O,S)$, there is a unique $\Sigma$-homomorphism $f:\mathbb N\to A$ defined by the same two equations above.

Answer. [^aos]

[^aos]: By the property of a homomorphism, we must have $f(0)=\rm O$ and $f(n+1)=s(f(n))$. This determines $f$ uniquely.

In pseudo Haskell, we can define this induction principle as (see also the code in [`induction`](https://repl.it/@alexhkurz/induction#main.hs)) 

```haskell=
induction :: a -> (a -> a) -> (Integer -> a)
induction i s 0 = i
induction i s (n+1) = s (induction i s n)
```

Note how lines 2 and 3 are exactly the same as the two equations above if we identify $f$ with `induction i s`. 

### Natural Numbers as a Free Monoid

This example shows that we get a different induction principle for the natural numbers if we change the signature. 

**Maths Exercise:** The natural numbers $(\mathbb N,0,+)$ are isomorphic to the free monoid over $\Sigma=\{s\}$.

Answer. [^NNfreemonoid]

**The induction principle:** For any monoid $(M,e,\cdot)$ and any $m\in M$ there is a unique monoid morphism $f:\mathbb N\to M$ satisfying
\begin{gather}
f(0) = e \\
f(n+1) = m \cdot f(n)
\end{gather}

$f(n)$ is more commonly written as $m^n$. What the inductive definition explains is why this notation not only makes sense for numbers but generalises to any monoid.

**Maths Exercise:** Prove the uniqueness of $f$.

Answer. [^uniqueness]

[^uniqueness]: Consider $f'$ with $f'(1)=m$. We have to show $f'=f$. We know $f(0)=f'(0). (Why?) Morevover, for $n=1+\ldots 1$, $n>0$, we have $f'(n)=f'(1+\ldots 1) = f'(1)\cdot\ldots f'(1)= f(1)\cdot\ldots f(1) = f(1+\ldots 1) = f'(n)$.

In pseudo Haskell, the induction principle can be defined as (see also the code in [`induction`](https://repl.it/@alexhkurz/induction#main.hs))

```haskell=
induction2 :: m -> (m->m->m) -> m -> Int -> m
induction2 e mult m 0 = e
induction2 e mult m (n+1) = mult m (induction2 e mult m n)
```

Again, identifying $f$ in the two equations above with `induction2 e mult m` we have a perfect match between code and maths.

**Exercise:** Adapt the definitions above to the situation where one does not have a neutral element. [^semigroup]

[^semigroup]: The structure arising from dropping the neutral element and identity laws from the definition of monoids is known as semi-group.

### Induction over Words/Lists

Words (= lists) are algebras for two different signatures. First, we have the signature where each letter is a unary operation. Second, we have the signature of monoids. Induction over words usually refers to the first signature. Let us review an example.

If we write 

```haskell
data List a = Nil | Cons a (List a)
```

we define `List a` as a particular algebra (in fact the initial algebra or termalgebra, see below) for the signature [^xina]  $$\Sigma = \{\tt Nil\} \cup \{{\tt Cons\ x} \mid {\tt x} \in \tt a\}$$  

where $\{\tt Nil\}$ is a constant (arity $0$) and the ${\tt Cons\ x}$  are unary (arity $1$). When we define length of a list via

```haskell
len :: List a -> Integer
len Nil = 0
len (Cons x xs) = 1 + len xs
```

we define `len` as a structure preserving map, in fact a $\Sigma$-algebra homomorphism.

**Exercise:** For which algebraic structure on `Integer` is `len` a $\Sigma$-algebra homomorphism?

Answer. [^len]

[^len]: To understand `len` as a $\Sigma$-algebra homomorphism, we need to think of `Integer` as a $\Sigma$-algebra, that is, we need an interpretation on `Integer` of the operation symbols $\{\tt Nil\}$ and ${\tt Cons\ x}$. The Haskell definition of `len` does this implicitely: `Nil` is interpreted as `0` and all `Conx x` are interpreted as `1+`.


We used the following induction principle to extend the transition function of an automaton from letters to words.

Let $(M,e,\cdot)$ be a monoid. Any function $f:\Sigma\to M$ has a unique extension $f^\sharp:\Sigma^\ast\to M$.

In more detail, for any $f:\Sigma\to M$ there is a unique monoid homomorphism $$f^\sharp:\Sigma^\ast\to M$$ 

such that $f^\sharp([a])=f(a)$.

In Haskell, the induction principle can be defined as (see also the code in [`induction`](https://repl.it/@alexhkurz/induction#main.hs))


```haskell
fold :: m -> (m->m->m) -> (a->m) -> List a -> m
fold e mult f Nil = e
fold e mult f (Cons x xs) = mult (f x) (fold e mult f xs)  
```

The first two arguments are the monoid $M$ and the third argument is the function $f:\Sigma\to M$.

**Programming Exercise:** Implement the following functions using `fold`.
- a function `List Int -> Int` computing the sum of a list of integers.
- a function `List Int -> Int` computing the product of a list of integers.
- a function `List a -> Int` computing the length of a list.
- a function `List (List a) -> List a` that flattens a list (like `concat` does for Haskell's predefined lists).
- a function `List (List a) -> Int` that computes the sum of the lengths of the lists in a list.

Btw, instead of a programming exercise, this can also be seen as an exercise in writing down mathematical defintions.

**Programming Exercise:** Redo the exercises above with Haskell's predefined lists.

### Recursion over Algebraic Data Type

Every signature gives rise to a recursion principle. We can take for example binary trees.

By the way, here we see again why for applications it is usually necessary/convenient to generalise our definitions so that they allow for many-sorted/typed algebras.  For example, for binary trees over integers, we want to sorts/types, say, $T$ for trees and $\mathbb Z$ for integers and operations [^many-sorted]
\begin{align}
Nil & : 1 \to T\\
Node & : \mathbb Z\times T\times T \to T
\end{align}
The first makes an empty tree and the second makes a bigger tree from a left subtree, a right subtree and an integer. 

See the Homework on Algebraic Data Types below for more.

[^many-sorted]: From a universal algebra point of view, there are two ways to treat $\mathbb Z$ in the example of binary trees. We can take $\mathbb Z$ as a parameter of the definition. Or we can take $\mathbb Z$ as a second sort and explicitely add the integer-operations with their equations to a 2-sorted algebra. There can be subtle differences between these two ways of modelling, but they do not need to concern us here. In case you want to know, for what we are doing here, I find it easier to consider $\mathbb Z$ as a parameter.



## Theory

(initial and free algebras will play an essential role in the next two lectures)

We continue from the section on axioms and universal algebra. 

The principle of induction we have seen at work in the previous examples is  induction over the set of all terms formed from the operations of a signature. The set of all terms these terms forms again an algebra. For example, the set $\{\rm O, SO, SSO,\ldots\}$ is closed under taking successors.

**Definition:** Let $\Sigma$ be a signature and let $X$ be a set of "variables". The set ${\sf Term}_{\Sigma,X}$ of all "terms" is the smallest set closed under the rules 

$$\frac{t_1,\ldots t_n \in {\sf Term}_{\Sigma,X}}{\sigma(t_1,\ldots t_n)\in {\sf Term}_{\Sigma,X}}\quad \sigma\in\Sigma, {\sf arity}(\sigma)=n
\quad\quad\quad\quad
\frac{}{x\in{\sf Term}_{\Sigma,X}}\quad x\in X
$$

We write ${\sf Term}_{\Sigma}$ if $X$ is empty. ${\sf Term}_{\Sigma,X}$ is a $\Sigma$-algebra, the **termalgebra** over $\Sigma$ and $X$, under the operations 
$$\overline \sigma : ({\sf Term}_{\Sigma,X})^n\to{\sf Term}_{\Sigma,X}$$

defined by the rule on the left above. 


**Proposition:** Fix a signature $\Sigma$. 
1. For any algebra $A$ there is a unique homomorphism 
$${\sf Term}_\Sigma\to A$$

2. For any algebra $A$, set of variables $X$, and function $f:X\to A$, there is a unique homomorphism 
$$f^\sharp: {\sf Term}_{\Sigma,X}\to A$$ 

    such that $f^\sharp(x) = f(x)$.

**Maths Exercise:** Prove the proposition by induction on the structure of the termalgebra.

**Maths Exercise:** In the section on examples on induction and the program [`induction`](https://repl.it/@alexhkurz/induction#main.hs), we saw the definition

```haskell=
fold :: m -> (m->m->m) -> (a->m) -> List a -> m
fold e mult f Nil = e
fold e mult f (Cons x xs) = mult (f x) (fold e mult f xs)  
```

Show that `fold` is the unique homomorphism from the free monoid `List a` over `a` to a monoid `(m,e,mult)` wrt `f:a->m`, that is, 
\begin{gather}
\texttt{fold e mult f} = \texttt{f}^\sharp
\end{gather}

Answer. [^foldMon]

The existence and uniqueness of the homomorphism is called the universal property of the termalgebra. An algebra with Property 1 is also called an *initial algebra* and an algebra with Property 2 a *free algebra* over $X$.

Notice that the fact that the termalgebra has the universal property is proved by induction. Conversely, when we will study category theory in the next lecture, we will take the universal property of an initial algebra as an axiomatisation of induction.


## Applications

(can be skipped if the importance of structure preserving maps is appreciated)

We will present two applications of the concept of structure preserving maps, one to mathematics and one to theoretical computer science. An application to programming will be presented as homework below.

1. The mathematical application uses the notion of structure preserving map to answer the question whether there are more fractions than integers in two different, seemingly contradictory ways. The apparent paradox will be solved by paying attention to the notion of struture implicit in the two answers.

2. The theoretical computer science application uses the notion of structure preserving map to give a mathematical answer to the following question. What is the meaning of a programming language?

3. The application to programming is to show that the unique homomorphism from the termalgebra can be programmed by recursion over an algebraic data type.

### Are there more rational numbers than integers?

What do you think: Are there more fractions than integers?

(This is one of those questions where both yes and no can be a correct answer depending on how you justify it.)

**Convention:** I restrict my attention to positive rationals and positive integers and I denote them by $\mathbb Q$ and $\mathbb N$, respectively. The answers remain true if we extend to all rationals and integers.

#### Answer 1: There are strictly more rationals than integers

It seems obvious that there are more rationals than integers.

We can visualise this by looking at the numberline where there are gaps between integers, but the rationals are dense.

In symbolic notation, we look at the inclusion

$$\mathbb N\hookrightarrow \mathbb Q$$

which is injective but not surjective, hence not bijective: Every integer is a rational, but there are rationals that are not integers.


#### Answer 2: There are at least as many integers as rationals

Can we encode rationals by integers? After all, we know that rationals are stored in a computer as sequences of bits and that every sequence of bit is an integer in [binary notation](https://en.wikipedia.org/wiki/Binary_number). This suggests that there is an injective function

$$\mathbb Q\to \mathbb N$$

showing that there are at least as many rationals as integers. Equivalently, and easier to explain, we can also look for a surjective function

$$\mathbb N\to \mathbb Q$$

We guess, from the fact that rationals can be represented on a digital computer, that such a map must exist.

But what is an easy way to describe such a map explicitely?

It was found by [Cantor](https://en.wikipedia.org/wiki/Georg_Cantor) and is most easily given by [a picture](https://www.geeksforgeeks.org/n-th-term-of-george-cantor-set-of-rational-numbers/). You can derive from the picture an algorithm that computes the functions $\mathbb Q\to \mathbb N$ and $\mathbb N\to \mathbb Q$ via going through a while loop. You can also challenge your math-muscles and derive an explicit formula that does not need going through a loop.

**Remark:** The map $\mathbb N\to \mathbb Q$ given by the [picture](https://www.geeksforgeeks.org/n-th-term-of-george-cantor-set-of-rational-numbers/) assigns more than one code to each rational as eg $1/2=2/4$. Thus the picture gives a surjective but not bijective $\mathbb N\to \mathbb Q$. But we can define a bijective map from it by eliminating duplicate codes. 

It seems that we reached a contradiction between Answer 1 and Answer 2. 

Thinking about it, it looks like Answer 2 is winning. Because, by reaching Answer 1, we made a mistake. We argued that an map $A\to B$ that is injective but not surjective proves that there are strictly more $B$ than $A$. This is true for finite sets, but wrong for infinite sets.

Nevertheless, Answer 1 looks intuitively correct. So can we restore our intuition and justify it by an explanation that stands up to scientific standards of scrutiny?

The answer is yes and what we need for the justification is the notion of structure preserving map.

**Exercise/Activity:** Can you lead the development we abandoned with the last sentence to a satisfying conclusion?

### Denotational Semantics of Programming Languages

The abstract syntax of a programming language can be  described in terms of universal algebra. For example, the abstract syntax of $\lambda$-calculus

```haskell
data Exp = Var String | App Exp Exp | Abs String Exp
```

corresponds to a two-sorted universal algebra, one sort `String` for variables and one sort for expressions, as well as two operations, one for application and one for abstraction. 

Before we come back to $\lambda$-calculus let us first look at the example of arithmetic. For example, if we take as abstract syntax of a simple language of arithmetic

```haskell
data Exp = 1 | Add Exp Exp | Mult Exp Exp
```

this corresponds to a signature $\Sigma= \{1,+,*\}$. The meaning of this language can be described as the unique homomorphism
$${\sf Term_\Sigma} \to (\mathbb N,1, +,\cdot)$$

For more on this perspective see my lecture on [operational and denotational semantics](https://hackmd.io/@alexhkurz/Hkf6BTL6P).

Now let us quickly come back to the question why we need to go beyond universal algebra, if we want to extend these techniques from arithmetic to $\lambda$-calculus and other programming languages.

- Universal algebra only supports operations of type $A^n\to A$. To treat typed functional programming languages, we need to extend universal algebra with a more expressive type system, and this is one reason why category theory, to be introduced in the next lecture, is of such importance in programming language research.
- A more subtle point is that universal algebra does not provide us with tools to deal with variable binding, the distinction between free and bound variables, $\alpha$-equivalence, capture avoiding substitution. [^substitution] [^salibra] These issues are pursued in an area of theoretical computer science known as  nominal sets or nominal techniques. [^gabbaypitts]

[^substitution]: For example, the capture avoiding substitution of $\lambda$-calculus is very different from the substitution into free variables one has in universal algebra.

[^salibra]: Nevertheless, universal algebraic techniques can be used to prove powerful results about $\lambda$-calculus, see eg the work of Antonino Salibra.

[^gabbaypitts]: See the work by Gabbay and Pitts.

For more on variables and binding see my lecture []().


## Homework

### (Maths) $X^\ast$ is the free monoid over $X$

(prove that `List a` is the free monoid over `a`)

In the previous lecture we defined $X^\ast$ (or `List a`) and called it the free monoid. In the next lecture we will see an independent definition of free algebra. To show that these two definitions agree, one has to show the following.

Let $(M,e,*)$ be a monoid. For any map $f:X\to M$ there is a unique monoid homomorphism $f^\sharp:X^\ast\to M$ such that $$f^\sharp([x]) = f(x).$$

- Define multiplication (=concatenation) on lists inductively.
- Define $f^\sharp$ inductively.
- Show that $f^\sharp([x]) = f(x)$.
- Show that $f^\sharp([]) = e$.
- Show that $f^\sharp$ preserves multiplication.

**Remark:** We will see in Lecture 4 that all free algebras correspond to monads, and vice versa. But there is something special about the example of lists:

- $X^\ast$ is the free algebra over the empty set for the signature $\Sigma = \{[]\}\cup X$ where the arity of $[]$ is 0 and the arity of the elements $x\in X$ is $1$.
- $X^\ast$ is the free monoid over $X$.

It may be interesting to think about the analogy `List a` and `BTree a`, see the below, and to try to turn `BTree` into a monad/free algebra over `a`.

### (Programming) Recursion over Algebraic Data Types

(if you want to do some programming, this homework illustrates that inductively-defined structure-preserving maps on termalgebras can be run on a computer)

As an application I will show that we can program with the univeral property of initial algebras, at least if no equations are involved. I will use Haskell, but everything is entirely general and can be made to work in any programming language (possibly in a more cumbersome notation).

Head over to [`algebraic-data-types`](https://repl.it/@alexhkurz/algebraic-data-types-1) to run and implement some Haskell functions defined by the univeral property of initial algebras.

Type `:load main.hs` into the  console on the right to call individual functions and use "run" to execute the test defined in `main`.  

We have seen that the natural numbers come with at least two induction principles, one for the signature of zero and successor and one for the natural numbers as monoids. The first one has the advantage that definition of natural numbers via zero and successor does not involve any equations. For such structures Haskell can run definitions by induction automatically.

The first line defines the natural numbers as an intial algebra (algebraic data type) in Haskell:

```haskell
data NN = Zero | Succ NN
```

Mathematically, we would write this as two functions
\begin{align} 
Zero :  1\to \mathbb N\\
Succ : \mathbb N\to \mathbb N
\end{align}

If you already know about addition on $\mathbb N$ you want $Succ(n) = 1+n$. But the perspective we are taking here is that we *define* the natural numbers, from scratch.

So we go the other way round and define addition by induction on the structure that defines $\mathbb N$, namely zero and successor:

\begin{align} 
Zero + y &= y \\
Succ(n) + y &= Succ(n+y)
\end{align}

**Exercise:** Show, by induction on $n$, that $Succ(n)=1+n$.

In Haskell, the definition of addition looks almost the same: [^haskellsyntax]

[^haskellsyntax]: If you want to understand why Haskell syntax is different there are two (related) reasons. The first is historical: Haskell inherited its syntax from the $\lambda$-calculus. The second is that Haskell syntax is superior to the conventional maths syntax if one works with higher order functions. 

```haskell
add Zero y = y
add (Succ n) y = Succ (add n y)
```
One advantage of the Haskell syntax is that it actually runs. Enter in the console

```haskell
add (Succ Zero) (Succ Zero)
```
to obtain the result

```haskell
Succ (Succ Zero)
```

Next, we define in Haskell the free monoid over a type `a` 
```haskell
data List a = Nil | Cons a (List a)
```

Mathematically, replacing now `a` with $X$, we would write this as two functions [^mathematically]
\begin{align} 
 Nil &:  1\to X^\ast\\
Cons &: X\times X^\ast\to X^\ast
\end{align}

[^mathematically]: If you wonder why the Haskell notation and the mathematical notation are much closer for the functions like addition than for the definition of the data types: We will be able to remedy this in the next lecture when we introduce functors. In fact, a definition like `data List a` is best understood as defining a functor $List(X)$.

At this point, I slowly start to prefer Haskell to maths. Judge for yourself, but if you head over to `adt.hs`, dedinitions such as
```haskell
len Nil = 0
len (Cons x xs) = 1 + len xs
```

are neat enough that I don't want to repeat them in mathematical notation. (But try it as an exercise, just to make sure you can translate between the two ways of writing.)

After we have done this, we will also be in a position to understand better the remark that these operations are generic. For example, replay what we did so far for the data type of binary trees

```haskell
data BTree a = Nil | Node (BTree a) (BTree a) a 
```

and compare `BTree` and `List`. 

With binary trees one can define heap sort. The idea is to transform a list into a heap and then to flatten the heap into a sorted list.

Here is a definition of a heap:
- `Nil` is a heap.
- `Node t a n` is a heap if all nodes in `t` are $\le n$ and all nodes in `s` are $\ge n$.

Define the following functions.

```haskell
data BTree a = Nil | Node (BTree a) (BTree a) a 

member :: Eq a => BTree a -> a -> Bool

max_tree :: BTree Int -> Int

insert :: BTree Int -> Int -> BTree Int

heapify :: [Int] -> BTree Int

is_heap :: BTree Int -> Bool

flatten :: BTree Int -> [Int]
```

They should satisfy the property that ${\sf flatten \circ heapify} (xs)$ is sorted as well as the equations

\begin{align}
{\sf flatten \circ heapify} (xs) & = xs & {\textrm{ if  $xs$ is sorted}}\\
{\sf is\_heap \circ heapify} (xs) & = \sf True \\
...
\end{align}

### (Programming) A Binary Tree monad

For the bintary trees above there is no obvious way to define a `mu :: BTree (BTree a) -> BTree`. But if we store data only in the leaves that changes. At [`magma`](https://repl.it/@alexhkurz/magma#main.hs), you can implement a monad structure on 

```haskell
data Magma a = Leaf a | Node (Magma a) (Magma a)
```

From a programming point of view `Magma a` is a kind of binary tree. But `Magma a` is also the free [magma]() over `a`. [^freemagma]

## Summary and Outlook

In this lecture, we already have seen a lot of category theory, without calling it that. Indeed, by now, many of the main protagonsits have appeared: categories, functors, natural transformations, initial objects,  free algebras and left adjoints, monads, univeral properties. So it is time to reveal this structure in the next lecture.

## References and Further Reading

... ask me if you are interested ...


[^xina]: Instead of ${\tt x} \in \tt a$ we could also write $\tt x :: a$, using Haskell's notation ` x ::  a` to indicate that `x` is an element of type `a`. 

[^freemagma]: Let $\Sigma$ be a signature with one binary operation symbol. Then `Magma a` is ${\sf Term}_{\Sigma,\tt a}$.

[^NNfreemonoid]: The free monoid $M$ over $\Sigma=\{s\}$ has elements $\epsilon, s, ss, sss, \ldots$. Define $f:M\to \mathbb N$ as $f(w) = length(w)$. $f$ is a bijection (why?). And $f$ preserves the monoid structure. Indeed, $f(\epsilon)=0$ and $f(wv) = length(wv) = length(w)+length(v) = f(w) + f(v)$.


[^foldMon]: We let $\Sigma$ be the signature of monoids (one unary operation, one binary operation). Then `List a` is isomorphic to the termalgebra $$\sf{Term}_{\Sigma,\texttt{a}}.$$ 

    If `e :: m` and `mult :: m->m->m` satisfy the equations of a monoid, then $(\tt m, e, mult)$ is a monoid. Therefore, by the universal property of the termalgebra,  any `f::a->m` induces a unique monoid homomorphism $$\tt f^\sharp::\sf{Term}_{\Sigma,\texttt{a}} \longrightarrow (\tt m, e, mult).$$
    
    It remains to show that $\tt f^\sharp$ is indeed `foldMon e mult f`. This is similar to this  [exercise](https://hackmd.io/pk5Q2oBxS4id0zWNd5PvQA?view#span-idMathJax-Element-664-Frame-classmjx-chtml-MathJax_CHTML-tabindex0-stylefont-size-114-position-relative-data-mathmlXampx2217-rolepresentationX%E2%88%97X%E2%88%97Xast-is-the-free-monoid-over-span-idMathJax-Element-665-Frame-classmjx-chtml-MathJax_CHTML-tabindex0-stylefont-size-114-position-relative-data-mathmlX-rolepresentationXXX).


