Revision as of 08:26, 14 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.
1 Recursion patterns
((X, Y and Z)) identified in the paper ((Bananas et.c.)) a number of generic patterns for recursive programming that they had observed, catalogued and systematized. The aim of that paper is to establish a number of rules for modifying and rewriting expressions involving these generic recursion patterns.
As it turns out, these patterns are instances of the same phenomenon we saw last lecture: where the recursion comes from specifying a different algebra, and then take a uniquely existing morphism induced by initiality (or, as we shall see, finality).
Before we go through the recursion patterns, we need to establish a few pieces of theoretical language, dualizing the Eilenberg-Moore algebra constructions from the last lecture.
1.1 Coalgebras for endofunctors
Definition If is an endofunctor, then a P-coalgebra on A is a morphism .
A morphism of coalgebras: is some such that the diagram
Just as with algebras, we get a category of coalgebras. And the interesting objects here are the final coalgebras. Just as with algebras, we have
Lemma (Lambek) If is a final coalgebra, it is an isomorphism.
Finally, one thing that makes us care highly about these entities: in an appropriate category (such as ω − CPO), initial algebras and final coalgebras coincide, with the correspondence given by inverting the algebra/coalgebra morphism. In Haskell not quite true (specifically, the final coalgebra for the lists functor gives us streams...).
Onwards to recursion schemes!
A catamorphism is the uniquely existing morphism from an initial algebra to a different algebra. We have to define maps down to the return value type for each of the constructors of the complex data type we're recursing over, and the catamorphism will deconstruct the structure (trees, lists, ...) and do a generalized fold over the structure at hand before returning the final value.
The intuition is that for catamorphisms we start essentially structured, and dismantle the structure.
Example: the length function from last lecture. This is the catamorphism for the functor given by the maps
u :: Int u = 0 m :: (A, Int) -> Int m (a, n) = n+1
An anamorphism is the categorical dual to the catamorphism. It is the canonical morphism from a coalgebra to the final coalgebra for that endofunctor.
Here, we start unstructured, and erect a structure, induced by the coalgebra structures involved.
Example: we can write a recursive function
first :: Int -> [Int] first 1 =  first n = n : first (n - 1)
This is an anamorphism from the coalgebra for on generated by the two maps
c 0 = Left () c n = Right (n, n-1)
and we observe that we can chase through the diagram
to conclude that therefore
f 0 =  f n = n : f (n - 1)
which is exactly the recursion we wrote to begin with.
2 Further reading
Terminology in the literature: in and out, inl, inr.
- Write a fold for the data type and demonstrate how this can be written as a catamorphism by giving the algebra it maps to.data T a = L a | B a a | C a a a
- The integers have a partial order induced by the divisibility relation. We can thus take any integer and arrange all its divisors in a tree by having an edge if d | n and d doesn't divide any other divisor of n. Write an anamorphic function that will generate this tree for a given starting integer. Demonstrate how this function is an anamorphism by giving the algebra it maps from.