User:Ezrakilty/Draft of Anamorphism as pattern of function definition
From Wikipedia, the free encyclopedia
In functional programming, an anamorphism is a function defined according to a certain pattern, which builds up results of an type one constructor at a time from a seed. The term comes from Greek ἀνά (upwards) + morphism (from Greek μορφή, or form, shape) and the concept has its grounding in Category theory.
The concept of anamorphism generalizes the list-producing unfold functions to arbitrary algebraic data types. In fact, the terms 'anamorphism' and "unfold" (as a noun) are often used interchangeably. Anamorphisms, which are co-recursive, are dual to catamorphisms, which are recursive, just as unfolds are dual to folds.
Examples
Anamorphisms on Lists
An anamorphism on lists builds a (potentially infinite) list from a seed value and a construction function.
In terms of a predicate finished :: b -> Bool and a function step :: b -> (a,b), a list anamorphism f has the following definition (in Haskell syntax):
f x | finished x = []
| otherwise = a : f y
where (a, y) = step x
Such a function takes a seed value, x and checks whether it is "finished" in which case it simply returns the empty list. If not, it uses the step operation to generate a "next" list element and a new seed; it generates the rest of the list by recursing with the new seed.
This pattern can be abstracted into a higher-order function definition, as followss:
-- The type signature of 'ana':
ana :: (b->(a,b)) -> (b->Bool)-> b -> [a]
-- Its definition:
ana step finished x = f x
where
f x | finished x = []
| otherwise = a : f y
where (a, y) = step x
Anamorphisms on other data structures
An anamorphism can be defined for any recursive type, according to a generic pattern. For example, the unfold for the tree data structure
data Tree a = Leaf a | Branch Tree a Tree
is as follows
ana :: (b->Either a (b,a,b)) -> b -> Tree a
ana unspool x = case unspool x of
Left a -> Leaf a
Right (l,x,r) -> Branch (ana unspool l) x (ana unspool r)