# User:Michiexile/MATH198/Lecture 8

### From HaskellWiki

Michiexile (Talk | contribs) |
Michiexile (Talk | contribs) |
||

Line 72: | Line 72: | ||

:[[Image:GroupDiagram.png]] | :[[Image:GroupDiagram.png]] | ||

+ | We can summarize the diagram as | ||

+ | :<math>1+G+G\times G \mapsto^{[u,i,m]} G</math> | ||

+ | and thus recognize that groups are some equationally defined subcategory of the category of <math>T</math>-algebras for the polynomial functor <math>T(X) = 1 + X + X\times X</math>. The subcategory is ''full'', since if we have two algebras <math>\gamma: T(G)\to G</math> and <math>\eta: T(H)\to H</math>, that both lie within the subcategory that fulfills all the additional axioms, then certainly any morphism <math>\gamma\to\eta</math> will be compatible with the structure maps, and thus will be a group homomorphism. | ||

+ | ---- | ||

+ | |||

+ | We shall denote the category of <math>P</math>-algebras in a category <math>C</math> by <math>P-Alg(C)</math>, or just <math>P-Alg</math> if the category is implicitly understood. | ||

+ | |||

+ | This category is wider than the corresponding concept for a monad. We don't require the kind of associativity we would for a monad - we just lock down the underlying structure. This distinction is best understood with an example: | ||

+ | |||

+ | The free monoids monad has monoids for its algebras. On the other hand, we can pick out the underlying functor of that monad, forgetting about the unit and multiplication. An algebra over this structure is a slightly more general object: we no longer require <math>(a\cdot b)\cdot c = a\cdot (b\cdot c)</math>, and thus, the theory we get is that of a ''magma''. We have concatenation, but we can't drop the brackets, and so we get something more reminiscent of a binary tree. | ||

+ | |||

+ | ===Initial <math>P</math>-algebras and recursion=== | ||

+ | |||

+ | Consider the polynomical functor <math>P(X) = 1 + X</math> on the category of sets. It's algebras form a category, by the definitions above - and an algebra needs to pick out one special element 0, and one endomorphism T, for a given set. | ||

+ | |||

+ | What would an initial object in this category of P-algebras look like? It would be an object <math>I</math> equipped with maps <math>1 \to^o I \leftarrow^n I</math>. For any other pair of maps <math>a: 1\to X, s: X\to X</math>, we'd have a unique arrow <math>u: I\to X</math> such that | ||

+ | :[[Image:NNOcommutes.png]] | ||

+ | commutes, or in equations such that | ||

+ | :<math>u(o) = a</math> | ||

+ | :<math>u(n(x)) = s(u(x))</math> | ||

+ | |||

+ | Now, unwrapping the definitions in place, we notice that we will have elements <math>o, n(o), n(n(o), \dots</math> in <math>I</math>, and the initiality will force us to not have any ''other'' elements floating around. Also, intiality will prevent us from having any elements not in this minimally forced list. | ||

+ | |||

+ | We can rename the elements to form something more recognizable - by equating an element in <math>I</math> with the number of applications of <math>n</math> to <math>o</math>. This yields, for us, elements <math>0, 1, 2, \dots</math> with one function that picks out the <math>0</math>, and another that gives us the cussessor. | ||

+ | |||

+ | This should be recognizable as exactly the natural numbers; with just enough structure on them to make the principle of mathematical induction work: suppose we can prove some statement <math>P(0)</math>, and we can extend a proof of <math>P(n)</math> to <math>P(n+1)</math>. Then induction tells us that the statement holds for all <math>P(n)</math>. | ||

+ | |||

+ | More importantly, recursive definitions of functions from natural numbers can be performed here by choosing an appropriate algebra mapping to. | ||

+ | |||

+ | This correspondence between the initial object of <math>P(X) = 1 + X</math> is the reason such an initial object in a category with coproducts and terminal objects is called a ''natural numbers object''. | ||

+ | |||

+ | For another example, we consider the functor <math>P(X) = 1 + X\times X</math>. | ||

+ | |||

+ | '''Pop Quiz''' Can you think of a structure with this as underlying defining functor? | ||

+ | |||

+ | An initial <math>1+X\times X</math>-algebra would be some diagram | ||

+ | :<math>1 \to^o I \leftarrow^m I\times I</math> | ||

+ | such that for any other such diagram | ||

+ | :<math>1 \to^a X \leftarrow^* X\times X</math> | ||

+ | we have a unique arrow <math>u:I\to X</math> such that | ||

+ | :[[Image:MonoidCommutes.png]] | ||

+ | commutes. | ||

+ | |||

+ | Unwrapping the definition, working over Sets again, we find we are forced to have some element <math>*</math>, the image of <math>o</math>. Any two elements <math>S,T</math> in the set give rise to some <math>(S,T)</math>, which we can view as being the binary tree | ||

+ | :[[Image:MagmaComposition.png]] | ||

+ | |||

+ | The same way that we could construct induction as an algebra map from a natural numbers object, we can use this object to construct a tree-shaped induction; and similarily, we can develop what amounts to the theory of ''structural induction'' using these more general approaches to induction. | ||

+ | |||

+ | ====Example of structural induction==== | ||

+ | |||

+ | Using the structure of <math>1+X\times X</math>-algebras we shall prove the following statement: | ||

+ | |||

+ | '''Proposition''' The number of leaves in a binary tree is one more than the number of internal nodes. | ||

+ | |||

+ | '''Proof''' We write down the actual Haskell data type for the binary tree initial algebra. | ||

+ | <haskell> | ||

+ | data Tree = Leaf | Node Tree Tree | ||

+ | |||

+ | nLeaves Leaf = 1 | ||

+ | nLeaves (Node s t) = nLeaves s + nLeaves t | ||

+ | |||

+ | nNodes Leaf = 0 | ||

+ | nNodes (Node s t) = 1 + nNodes s + nNodes t | ||

+ | </haskell> | ||

+ | |||

+ | Now, it is clear, as a base case, that for the no-nodes tree <hask>Leaf</hask>: | ||

+ | <haskell> | ||

+ | nLeaves Leaf = 1 + nNodes Leaf | ||

+ | </haskell> | ||

+ | |||

+ | For the structural induction, now, we consider some binary tree, where we assume the statement to be known for each of the two subtrees. Hence, we have | ||

+ | <haskell> | ||

+ | tree = Node s t | ||

+ | |||

+ | nLeaves s = 1 + nNodes s | ||

+ | nLeaves t = 1 + nNodes t | ||

+ | </haskell> | ||

+ | and we may compute | ||

+ | <haskell> | ||

+ | nLeaves tree = nLeaves s + nLeaves t | ||

+ | = 1 + nNodes s + 1 + nNodes t | ||

+ | = 2 + nNodes s + nNodes t | ||

+ | |||

+ | nNodes tree = 1 + nNodes s + nNodes t | ||

+ | </haskell> | ||

+ | |||

+ | Now, since the statement is proven for each of the cases in the structural description of the data, it follows form the principle of structural induction that the proof is finished. | ||

+ | |||

+ | In order to really nail down what we are doing here, we need to define what we mean by predicates in a strict manner. There is a way to do this using ''fibrations'', but this reaches far outside the scope of this course. For the really interested reader, I'll refer to [http://www.springerlink.com/content/d022nlv03n26nm03/]. | ||

+ | |||

+ | ====Lambek's lemma==== | ||

+ | |||

+ | What we do when we write a recursive data type definition in Haskell ''really'' to some extent is to define a data type as the initial algebra of the corresponding functor. This intuitive equivalence is vindicated by the following | ||

+ | |||

+ | '''Lemma''' ''Lambek'' If <math>P: C\to C</math> has an initial algebra <math>I</math>, then <math>P(I) = I</math>. | ||

+ | |||

+ | Thus, by Lambek's lemma we ''know'' that if <math>P_A(X) = 1 + A\times X</math> then for that <math>P_A</math>, the initial algebra - should it exist - will fulfill<math>I = 1 + A\times I</math>, which in turn is exactly what we write, defining this, in Haskell code: | ||

+ | <haskell> | ||

+ | List a = Nil | Cons a List | ||

+ | </haskell> | ||

+ | |||

+ | ====Recursive definitions with the unique maps from the initial algebra==== | ||

+ | |||

+ | Consider the following <math>P_A(X)</math>-algebra structure <math>l: P_A(\mathbb N)\to\mathbb N</math> on the natural numbers: | ||

+ | <haskell> | ||

+ | l(*) = 0 | ||

+ | l(a,n) = 1 + n | ||

+ | </haskell> | ||

+ | |||

+ | We get a unique map <math>f</math> from the initial algebra for <math>P_A(X)</math> (lists of elements of type <math>A</math>) to <math>\mathbb N</math> from this definition. This map will fulfill: | ||

+ | <haskell> | ||

+ | f(Nil) = l(*) = 0 | ||

+ | f(Cons a xs) = l(a,f(xs)) = 1 + f(xs) | ||

+ | </haskell> | ||

+ | which starts taking on the shape of the usual definition of the length of a list: | ||

+ | <haskell> | ||

+ | length(Nil) = 0 | ||

+ | length(Cons a xs) = 1 + length(xs) | ||

+ | </haskell> | ||

+ | |||

+ | And thus, the machinery of endofunctor algebras gives us a strong method for doing recursive definitions in a theoretically sound manner. | ||

===Homework=== | ===Homework=== |

## Revision as of 00:59, 11 November 2009

IMPORTANT NOTE: THESE NOTES ARE STILL UNDER DEVELOPMENT. PLEASE WAIT UNTIL AFTER THE LECTURE WITH HANDING ANYTHING IN, OR TREATING THE NOTES AS READY TO READ.

## Contents |

### 1 Algebras over monads

We recall from the last lecture the definition of an Eilenberg-Moore algebra over a monad *T* = (*T*,η,μ):

**Definition** An *algebra* over a monad *T* in a category *C* (a *T*-algebra) is a morphism , such that the diagrams below both commute:

While a monad corresponds to the imposition of some structure on the objects in a category, an algebra over that monad corresponds to some evaluation of that structure.

#### 1.1 Example: monoids

Let *T* be the Kleene star monad - the one we get from the adjunction of free and forgetful functors between Monoids and Sets. Then a *T*-algebra on a set *A* is equivalent to a monoid structure on *A*.

Indeed, if we have a monoid structure on *A*, given by and , we can construct a *T*-algebra by

- α([]) =
*u*

This gives us, indeed, a *T* < *m**a**t**h* > − *a**l**g**e**b**r**a**s**t**r**u**c**t**u**r**e**o**n* < *m**a**t**h* > *A*. Associativity and unity follows from the corresponding properties in the monoid.

On the other hand, if we have a *T*-algebra structure on *A*, we can construct a monoid structure by setting

*u*= α([])*m*(*a*,*b*) = α([*a*,*b*])

It is clear that associativity of *m* follows from the associativity of α, and unitality of *u* follows from the unitality of α.

(((potential headache: shouldn't η show up more? Instead of the empty list, maybe?)))

#### 1.2 Example: Vector spaces

We have free and forgetful functors

forming an adjoint pair; where the free functor takes a set *S* and returns the vector space with basis *S*; while the forgetful functor takes a vector space and returns the set of all its elements.

The composition of these yields a monad *T* in *S**e**t* taking a set *S* to the set of all formal linear combinations of elements in *S*. The monad multiplication takes formal linear combinations of formal linear combinations and multiplies them out:

- 3(2
*v*+ 5*w*) − 5(3*v*+ 2*w*) = 6*v*+ 15*w*− 15*v*− 10*w*= − 9*v*+ 5*w*

A *T*-algebra is a map that *acts like a vector space* in the sense that .

We can define and *v* + *w* = α(*v* + *w*). The operations thus defined are associative, distributive, commutative, and everything else we could wish for in order to define a vector space - precisely because the operations inside *T**A* are, and α is associative.

The moral behind these examples is that using monads and monad algebras, we have significant power in defining and studying algebraic structures with categorical and algebraic tools. This paradigm ties in closely with the theory of *operads* - which has its origins in topology, but has come to good use within certain branches of universal algebra.

An (non-symmetric) *operad* is a graded set equipped with composition operations that obey certain unity and associativity conditions. As it turns out, non-symmetric operads correspond to the summands in a monad with polynomial underlying functor, and from a non-symmetric operad we can construct a corresponding monad.

The designator non-symmetric floats in this text o avoid dealing with the slightly more general theory of symmetric operads - which allow us to resort the input arguments, thus including the symmetrizer of a symmetric monoidal category in the entire definition.

To read more about these correspondences, I can recommend you start with: the blog posts *Monads in Mathematics* here:
[1]

### 2 Algebras over endofunctors

Suppose we started out with an endofunctor that is not the underlying functor of a monad - or an endofunctor for which we don't want to settle on a monadic structure. We can still do a lot of the Eilenberg-Moore machinery on this endofunctor - but we don't get quite the power of algebraic specification that monads offer us. At the core, here, lies the lack of associativity for a generic endofunctor - and algebras over endofunctors, once defined, will correspond to non-associative correspondences to their monadic counterparts.

**Definition** For an endofunctor , we define a * P-algebra* to be an arrow .

A homomorphism of *P*-algebras is some arrow such that the diagram below commutes:

This homomorphism definition does not need much work to apply to the monadic case as well.

#### 2.1 Example: Groups

A group is a set *G* with operations , such that *u* is a unit for *m*, *m* is associative, and *i* is an inverse.

Ignoring for a moment the properties, the theory of groups is captured by these three maps, or by a diagram

We can summarize the diagram as

and thus recognize that groups are some equationally defined subcategory of the category of *T*-algebras for the polynomial functor . The subcategory is *full*, since if we have two algebras and , that both lie within the subcategory that fulfills all the additional axioms, then certainly any morphism will be compatible with the structure maps, and thus will be a group homomorphism.

We shall denote the category of *P*-algebras in a category *C* by *P* − *A**l**g*(*C*), or just *P* − *A**l**g* if the category is implicitly understood.

This category is wider than the corresponding concept for a monad. We don't require the kind of associativity we would for a monad - we just lock down the underlying structure. This distinction is best understood with an example:

The free monoids monad has monoids for its algebras. On the other hand, we can pick out the underlying functor of that monad, forgetting about the unit and multiplication. An algebra over this structure is a slightly more general object: we no longer require , and thus, the theory we get is that of a *magma*. We have concatenation, but we can't drop the brackets, and so we get something more reminiscent of a binary tree.

### 3 Initial *P*-algebras and recursion

Consider the polynomical functor *P*(*X*) = 1 + *X* on the category of sets. It's algebras form a category, by the definitions above - and an algebra needs to pick out one special element 0, and one endomorphism T, for a given set.

What would an initial object in this category of P-algebras look like? It would be an object *I* equipped with maps . For any other pair of maps , we'd have a unique arrow such that

commutes, or in equations such that

*u*(*o*) =*a**u*(*n*(*x*)) =*s*(*u*(*x*))

Now, unwrapping the definitions in place, we notice that we will have elements in *I*, and the initiality will force us to not have any *other* elements floating around. Also, intiality will prevent us from having any elements not in this minimally forced list.

We can rename the elements to form something more recognizable - by equating an element in *I* with the number of applications of *n* to *o*. This yields, for us, elements with one function that picks out the 0, and another that gives us the cussessor.

This should be recognizable as exactly the natural numbers; with just enough structure on them to make the principle of mathematical induction work: suppose we can prove some statement *P*(0), and we can extend a proof of *P*(*n*) to *P*(*n* + 1). Then induction tells us that the statement holds for all *P*(*n*).

More importantly, recursive definitions of functions from natural numbers can be performed here by choosing an appropriate algebra mapping to.

This correspondence between the initial object of *P*(*X*) = 1 + *X* is the reason such an initial object in a category with coproducts and terminal objects is called a *natural numbers object*.

For another example, we consider the functor .

**Pop Quiz** Can you think of a structure with this as underlying defining functor?

An initial -algebra would be some diagram

such that for any other such diagram

we have a unique arrow such that

commutes.

Unwrapping the definition, working over Sets again, we find we are forced to have some element * , the image of *o*. Any two elements *S*,*T* in the set give rise to some (*S*,*T*), which we can view as being the binary tree

The same way that we could construct induction as an algebra map from a natural numbers object, we can use this object to construct a tree-shaped induction; and similarily, we can develop what amounts to the theory of *structural induction* using these more general approaches to induction.

#### 3.1 Example of structural induction

Using the structure of -algebras we shall prove the following statement:

**Proposition** The number of leaves in a binary tree is one more than the number of internal nodes.

**Proof** We write down the actual Haskell data type for the binary tree initial algebra.

data Tree = Leaf | Node Tree Tree nLeaves Leaf = 1 nLeaves (Node s t) = nLeaves s + nLeaves t nNodes Leaf = 0 nNodes (Node s t) = 1 + nNodes s + nNodes t

nLeaves Leaf = 1 + nNodes Leaf

For the structural induction, now, we consider some binary tree, where we assume the statement to be known for each of the two subtrees. Hence, we have

tree = Node s t nLeaves s = 1 + nNodes s nLeaves t = 1 + nNodes t

and we may compute

nLeaves tree = nLeaves s + nLeaves t = 1 + nNodes s + 1 + nNodes t = 2 + nNodes s + nNodes t nNodes tree = 1 + nNodes s + nNodes t

Now, since the statement is proven for each of the cases in the structural description of the data, it follows form the principle of structural induction that the proof is finished.

In order to really nail down what we are doing here, we need to define what we mean by predicates in a strict manner. There is a way to do this using *fibrations*, but this reaches far outside the scope of this course. For the really interested reader, I'll refer to [2].

#### 3.2 Lambek's lemma

What we do when we write a recursive data type definition in Haskell *really* to some extent is to define a data type as the initial algebra of the corresponding functor. This intuitive equivalence is vindicated by the following

**Lemma** *Lambek* If has an initial algebra *I*, then *P*(*I*) = *I*.

Thus, by Lambek's lemma we *know* that if then for that *P*_{A}, the initial algebra - should it exist - will fulfill, which in turn is exactly what we write, defining this, in Haskell code:

List a = Nil | Cons a List

#### 3.3 Recursive definitions with the unique maps from the initial algebra

Consider the following *P*_{A}(*X*)-algebra structure on the natural numbers:

l(*) = 0 l(a,n) = 1 + n

We get a unique map *f* from the initial algebra for *P*_{A}(*X*) (lists of elements of type *A*) to from this definition. This map will fulfill:

f(Nil) = l(*) = 0 f(Cons a xs) = l(a,f(xs)) = 1 + f(xs)

which starts taking on the shape of the usual definition of the length of a list:

length(Nil) = 0 length(Cons a xs) = 1 + length(xs)

And thus, the machinery of endofunctor algebras gives us a strong method for doing recursive definitions in a theoretically sound manner.

### 4 Homework

- Find a monad whose algebras are
*associative algebras*: vector spaces with a binary, associative, unitary operation (multiplication) defined on them. Factorize the monad into a free/forgetful adjoint pair. - Find an endofunctor of
*H**a**s**k*whose initial object describes trees that are either binary of ternary at each point, carrying values from some*A*in the leaves. - Write an implementation of the monad of vector spaces in Haskell. If this is tricky, restrict the domain of the monad to, say, a 3-element set, and implement the specific example of a 3-dimensional vector space as a monad. Hint: [3] has written about this approach.