Description
Catamorphisms are generalizations of the concept of a fold in functional programming. A catamorphism deconstructs a data structure with an F-algebra for its underlying functor.
History
The name catamorphism appears to have been chosen by Lambert Meertens [1]. The category theoretic machinery behind these was resolved by Grant Malcolm [2][3], and they were popularized by Meijer, Fokkinga and Paterson[4][5]. The name comes from the Greek 'κατα-' meaning "downward or according to". A useful mnemonic is to think of a catastrophe destroying something.
Notation
A catamorphism for some F-algebra (X,f) is denoted (| f |)F. When the functor F can be determined unambiguously, it is usually written (|φ|) or cata φ. Due to this choice of notation, a catamorphism is sometimes called a banana and the (|.|) notation is sometimes referred to as banana brackets.
Haskell Implementation
A catamorphism is the categorical dual of an anamorphism.
Derivation
If (μF,inF) is the initial F-algebra for some endofunctor F and (X,φ) is an F-algebra, then there is a unique F-algebra homomorphism from (μF,inF) to (X,φ), which we denote (| φ |)F.
That is to say, the following diagram commutes:
Laws
Examples
The underlying functor for a string of Chars and its fixed point
A somewhat less common variation on the theme of a catamorphism is a catamorphism as a recursion scheme a la Mendler, which removes the dependency on the underlying type being an instance of Haskell's Functor typeclass [6].
The principal advantage of using Mendler-style is it is independent of the definition of the Functor definition for f.
Mendler and the Contravariant Yoneda Lemma
The definition of a Mendler-style algebra above can be seen as the application of the contravariant version of the Yoneda lemma to the functor in question.
In type theoretic terms, the contravariant Yoneda lemma states that there is an isomorphism between (f a) and ∃b. (b -> a, f b), which can be witnessed by the following definitions.
However, when used in the context of a (CoYoneda f)-Algebra, we can rewrite this to use universal quantification because the functor f only occurs in negative position, eliminating the spurious bottom.
Most more advanced recursion schemes for folding structures, such as paramorphisms and zygomorphisms can be seen in a common framework as "generalized" catamorphisms[7]. A generalized catamorphism is defined in terms of an F-W-algebra and a distributive law for the comonad W over the functor F which preserves the structure of the comonad W.
We can transform an F-W-algebra into an F-algebra by including the comonad in the carrier for the algebra and then extracting after we perform this somewhat more stylized catamorphism:
and we can trivially transform an Algebra into an F-W-Algebra by mapping the counit of the comonad over F. Then using the trivial identity functor, we can represent every catamorphism as a generalized-catamorphism.
Catamorphisms are generalizations of the concept of a fold in functional programming. A catamorphism deconstructs a data structure with an F-algebra for its underlying functor.
History
The name catamorphism appears to have been chosen by Lambert Meertens [1]. The category theoretic machinery behind these was resolved by Grant Malcolm [2][3], and they were popularized by Meijer, Fokkinga and Paterson[4][5]. The name comes from the Greek 'κατα-' meaning "downward or according to". A useful mnemonic is to think of a catastrophe destroying something.
Notation
A catamorphism for some F-algebra (X,f) is denoted (| f |)F. When the functor F can be determined unambiguously, it is usually written (|φ|) or cata φ. Due to this choice of notation, a catamorphism is sometimes called a banana and the (|.|) notation is sometimes referred to as banana brackets.
Haskell Implementation
Alternate Definitionstype Algebra f a = f a -> anewtype Mu f = InF { outF :: f (Mu f) }cata :: Functor f => Algebra f a -> Mu f -> acata f = f . fmap (cata f) . outF
Dualitycata f = hylo f outFcata f = para (f . fmap fst)
A catamorphism is the categorical dual of an anamorphism.
Derivation
If (μF,inF) is the initial F-algebra for some endofunctor F and (X,φ) is an F-algebra, then there is a unique F-algebra homomorphism from (μF,inF) to (X,φ), which we denote (| φ |)F.
That is to say, the following diagram commutes:
Laws
| Rule | Haskell |
|---|---|
| cata-cancel | cata phi . InF = phi . fmap (cata phi) |
| cata-refl | cata InF = id |
| cata-fusion | f . phi = phi . fmap f => f . cata phi = cata phi |
| cata-compose | eps :: f :~> g => cata phi . cata (In . eps) = cata (phi . eps) |
Examples
The underlying functor for a string of Chars and its fixed point
data StrF x = Cons Char x | Niltype Str = Mu StrF
instance Functor StrF wherefmap f (Cons a as) = Cons a (f as)fmap f Nil = Nil
The length of a string as a catamorphism.
length :: Str -> Intlength = cata phi wherephi (Cons a b) = 1 + bphi Nil = 0
The underlying functor for the natural numbers.
data NatF a = S a | Z deriving (Eq,Show)type Nat = Mu NatFinstance Functor NatF wherefmap f Z = Zfmap f (S z) = S (f z)
Addition as a catamorphism.
plus :: Nat -> Nat -> Natplus n = cata phi wherephi Z = nphi (S m) = s m
Multiplication as a catamorphism
Mendler Styletimes :: Nat -> Nat -> Nattimes n = cata phi wherephi Z = zphi (S m) = plus n mz :: Natz = InF Zs :: Nat -> Nats = InF . S
A somewhat less common variation on the theme of a catamorphism is a catamorphism as a recursion scheme a la Mendler, which removes the dependency on the underlying type being an instance of Haskell's Functor typeclass [6].
type MendlerAlgebra f c = forall a. (a -> c) -> f a -> c [8] From which we can derive the original notion of a catamorphism:mcata :: MendlerAlgebra f c -> Mu f -> cmcata phi = phi (mcata phi) . outF
This can be seen to be equivalent to the original definition of cata by expanding the definition of mcata.cata :: Functor f => Algebra f c -> Mu f -> ccata phi = mcata (\f -> phi . fmap f)
The principal advantage of using Mendler-style is it is independent of the definition of the Functor definition for f.
Mendler and the Contravariant Yoneda Lemma
The definition of a Mendler-style algebra above can be seen as the application of the contravariant version of the Yoneda lemma to the functor in question.
In type theoretic terms, the contravariant Yoneda lemma states that there is an isomorphism between (f a) and ∃b. (b -> a, f b), which can be witnessed by the following definitions.
Note that in Haskell using an existential requires the use of data, so there is an extra bottom that can inhabit this type that prevents this from being a true isomorphism.data CoYoneda f a = forall b. CoYoneda (b -> a) (f b)toCoYoneda :: f a -> CoYoneda f atoCoYoneda = CoYoneda idfromCoYoneda :: Functor f => CoYoneda f a -> f afromCoYoneda (CoYoneda f v) = fmap f v
However, when used in the context of a (CoYoneda f)-Algebra, we can rewrite this to use universal quantification because the functor f only occurs in negative position, eliminating the spurious bottom.
Generalized CatamorphismsAlgebra (CoYoneda f) a
= (by definition) CoYoneda f a -> a
~ (by definition) (exists b. (b -> a, f b)) -> a
~ (lifting the existential) forall b. (b -> a, f b) -> a
~ (by currying) forall b. (b -> a) -> f b -> a
= (by definition) MendlerAlgebra f a
Most more advanced recursion schemes for folding structures, such as paramorphisms and zygomorphisms can be seen in a common framework as "generalized" catamorphisms[7]. A generalized catamorphism is defined in terms of an F-W-algebra and a distributive law for the comonad W over the functor F which preserves the structure of the comonad W.
type Dist f w = forall a. f (w a) -> w (f a)type FWAlgebra f w a = f (w a) -> a
However, a generalized catamorphism can be shown to add no more expressive power to the concept of a catamorphism. That said the separation of a number of the "book keeping" concerns by isolating them in a reusable distributive law can ease the development of F-W-algebras.g_cata :: (Functor f, Comonad w) =>
Dist f w -> FWAlgebra f w a -> Mu f -> ag_cata k g = extract . c where
c = liftW g . k . fmap (duplicate . c) . outF
We can transform an F-W-algebra into an F-algebra by including the comonad in the carrier for the algebra and then extracting after we perform this somewhat more stylized catamorphism:
lowerAlgebra :: (Functor f, Comonad w) =>
Dist f w -> FWAlgebra f w a -> Algebra f (w a)lowerAlgebra k phi = liftW phi . k . fmap duplicate
g_cata :: (Functor f, Comonad w) =>
Dist f w -> FWAlgebra f w a -> Mu f -> ag_cata k phi = extract . cata (lowerGAlgebra k phi)
and we can trivially transform an Algebra into an F-W-Algebra by mapping the counit of the comonad over F. Then using the trivial identity functor, we can represent every catamorphism as a generalized-catamorphism.
Between these two definitions we can see that a generalized catamorphism does not increase the scope of a catamorphism to encompass any more operations, it simply further stylizes the pattern of recursion.liftAlgebra :: (Functor f, Comonad w) =>Algebra f a -> FWAlgebra f w a
liftAlgebra phi = phi . fmap extract
cata :: Functor f => Algebra f a -> Mu f -> a
cata f = g_cata (Identity . fmap runIdentity) (liftAlgebra f)
References
- L. Meertens. First Steps towards the theory of Rose Trees. Draft Report, CWI, Amsterdam, 1987.
- G. Malcolm. PhD. Thesis. University of Gronigen, 1990.
- G. Malcolm. Data structures and program transformation. Science of Computer Programming, 14:255--279, 1990.
- E. Meijer. Calculating Compilers, Ph.D Thesis, Utrecht State University, 1992.
http://research.microsoft.com/~emeijer/P apers/Thesis.pdf - E. Meijer, M. Fokkinga, R. Paterson, Functional Programming with Bananas, Lenses, Envelopes and Barbed Wire, 5th ACM Conference on Functional Programming Languages and Computer Architecture.
http://research.microsoft.com/~emeijer/P apers/fpca91.pdf - T. Uustalu, V. Vene. Coding Recursion a la Mendler. Proceedings 2nd Workshop on Generic Programming, WGP'2000, Ponte de Lima, Portugal, 6 July 2000
http://citeseer.ist.psu.edu/314266.html - T. Uustalu, V. Vene, A. Pardo. Recursion schemes from Comonads. Nordic Journal of Computing. Volume 8 , Issue 3 (Fall 2001). 366--390, 2001 ISSN:1236-6064
http://citeseer.ist.psu.edu/uustalu01rec ursion.html - E. Kmett. Catamorphism. The Comonad.Reader, 2008.
http://comonad.com/reader/2008/catamorph ism/





Murry Shohat
Invite as author
Congratulations, Honorable Mention
We are very pleased to announce that this Knol is an Honorable Mention badge winner for English Knols created in July 2008. Congratulations. You may view your award at http://knol.google.c
Top writers like you may benefit from participation in the 'Google Knol LinkedIn Group', located at http://www.linkedin.
Please consider joining with us to add your point of view. Knol is listening!
Great work, keep it up,
Murry Shohat and Peter Baskerville
Dark Magus
Invite as author
Отличная статья!
EditSaveCancelDeleteDeleteBlock this userReport abusive commentHide report window
I will translate your knol anyway as the addition to my one.
EditSaveCancelDeleteDeleteBlock this userReport abusive commentHide report window
EditSaveCancelDeleteDeleteBlock this userReport abusive commentHide report window
Max
Invite as author
Erratum
One very small correction: I think the single occurence of lowerGAlgebra in the code should be lowerAlgebra instead.