|
|
Line 1: |
Line 1: |
| {{other uses2|Anamorphosis}}
| | Andera is what you can call her but she never really liked that title. Distributing manufacturing is [http://www.010-5260-5333.com/index.php?document_srl=1880&mid=board_ALMP66 psychic readings online] where her primary earnings arrives from. Her family members lives in Alaska but her husband wants them to move. My husband doesn't like it the way I do but what I really like performing is caving but I don't have the time recently.<br><br>my web page ... accurate [http://www.seekavideo.com/playlist/2199/video/ cheap psychic readings] predictions ([http://www.youronlinepublishers.com/authWiki/AdolphvhBladenqq read article]) |
| | |
| In [[category theory]], the concept of '''anamorphism''' ("ana" from the Greek {{lang|grc|[[wikt:ἀνά|ἀνά]]}} = upwards; "morphism" from the Greek {{lang|grc|[[wikt:μορφή|μορφή]]}} = form, shape) denotes a [[morphism]] from a [[coalgebra]] to the [[Initial algebra|final coalgebra]] for that [[endofunctor]]. These objects have been applied to [[functional programming]] as ''[[Fold (higher-order function)|unfolds]]''. The [[categorical dual]] of the anamorphism is the [[catamorphism]].
| |
| | |
| == Anamorphisms in functional programming ==
| |
| | |
| In [[functional programming]], an '''anamorphism''' is a generalization of the concept of ''[[Fold (higher-order function)|unfolds]]'' on [[List (computing)|lists]]. Formally, anamorphisms are [[generic function]]s that can [[Corecursion|corecursively]] construct a result of a certain [[Algebraic data type|type]] and which is parameterized by functions that determine the next single step of the construction.
| |
| | |
| === Example ===
| |
| An ''unfold'' on [[List (computing)|lists]] would build a (potentially infinite) list from a seed value. Typically, the unfold takes a seed value <code>x</code>, a one-place operation <code>unspool</code> that yields a pairs of such items, and a predicate <code>finished</code> which determines when to finish the list (if ever). In the action of unfold, the first application of <code>unspool</code>, to the seed <code>x</code>, would yield <code>unspool x = (y,z)</code>. The list defined by the unfold would then begin with <code>y</code> and be followed with the (potentially infinite) list that unfolds from the second term, <code>z</code>, with the same operations. So if <code>unspool z = (u,v)</code>, then the list will begin <code>y:u:...</code>, where <code>...</code> is the result of unfolding v with r, and so on.
| |
| | |
| A [[Haskell (programming language)|Haskell]] definition of an unfold, or anamorphism for lists, called <code>ana</code>, is as follows:
| |
| | |
| <source lang="haskell">
| |
| -- The type signature of 'ana': | |
| ana :: (b -> (a, b)) -> (b -> Bool) -> b -> [a]
| |
| -- Its definition:
| |
| ana unspool finished x = if finished x
| |
| then []
| |
| else a:ana unspool finished y
| |
| where (a,y) = unspool x
| |
| </source>
| |
| (Here <code>finished</code> and <code>unspool</code> are parameters of the function, like <code>x</code>.)
| |
| | |
| In the case where we're finished (<code>finished x == True</code>), we do not use <code>unspool x</code>. We can thus group together <code>unspool</code> and <code>finished</code> into one function <code>f :: (b -> Maybe (a,b))</code>, where <code>f x = Just (a,y)</code> means <code>finished x == False</code> and <code>unspool x == (a,y)</code>, while <code>f x == Nothing</code> means we're done (<code>finished x == True</code>). We now have:
| |
| | |
| <source lang="haskell">
| |
| -- The type signature of 'ana':
| |
| ana :: (b -> Maybe (a,b)) -> b -> [a]
| |
| -- Its definition:
| |
| ana f x = case (f x) of
| |
| Nothing -> []
| |
| Just (a,y) -> a:(ana f y)
| |
| </source>
| |
| | |
| We can now implement quite general functions using ''ana''.
| |
| | |
| === Anamorphisms on other data structures ===
| |
| | |
| An anamorphism can be defined for any recursive type, according to a generic pattern, generalizing the second version of ''ana'' for lists.
| |
| | |
| For example, the unfold for the tree data structure
| |
| | |
| <source lang="haskell">
| |
| data Tree a = Leaf a | Branch (Tree a) a (Tree a)
| |
| </source>
| |
| | |
| is as follows
| |
| <source lang="haskell">
| |
| 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)
| |
| </source>
| |
| | |
| To better see the relationship between the recursive type and its anamorphism, note that Tree and List can be defined thus:
| |
| | |
| <source lang="haskell">
| |
| newtype List a = List {unCons :: Maybe (a, List a)}
| |
| | |
| newtype Tree a = Tree {unNode :: Either a (Tree a, a, Tree a))}
| |
| </source>
| |
| | |
| The analogy with <code>ana</code> appears by renaming <code>b</code> in its type:
| |
| | |
| <source lang="haskell">
| |
| newtype List a = List {unCons :: Maybe (a, List a)}
| |
| anaList :: ( list_a -> Maybe (a, list_a)) -> (list_a -> List a)
| |
| | |
| newtype Tree a = Tree {unNode :: Either a (Tree a, a, Tree a))}
| |
| anaTree :: (tree_a -> Either a (tree_a, a, tree_a)) -> (tree_a -> Tree a)
| |
| </source>
| |
| | |
| With these definitions, the argument to the constructor of the type has the same type as the return type of the first argument of ana, with the recursive mentions of the type replaced with <code>b</code>.
| |
| | |
| == History ==
| |
| | |
| One of the first publications to introduce the notion of an anamorphism in the context of programming was the paper ''Functional Programming with Bananas, Lenses, Envelopes and Barbed Wire'',<ref>{{cite web
| |
| |id = {{citeseerx|10.1.1.41.125}}
| |
| |title=Functional Programming with Bananas, Lenses, Envelopes and Barbed Wire
| |
| |first=Erik
| |
| |last=Meijer
| |
| |authorlink=Erik Meijer (computer scientist)
| |
| |author2=Fokkinga, Maarten|author3=Paterson, Ross
| |
| |year=1991
| |
| }}</ref> by [[Erik Meijer (computer scientist)|Erik Meijer]] ''et al.'', which was in the context of the [[Squiggol]] programming language.
| |
| | |
| ==Applications==
| |
| Functions like [[Zip (higher-order function)|<code>zip</code>]] and <code>iterate</code> are examples of anamorphisms. <code>zip</code> takes a pair of lists, say ['a','b','c'] and [1,2,3] and returns a list of pairs [('a',1),('b',2),('c',3)]. <code>Iterate</code> takes a thing, x, and a function, f, from such things to such things, and returns the infinite list that comes from repeated application of f, i.e. the list [x, (f x), (f (f x)), (f (f (f x))), ...].
| |
| | |
| <source lang="haskell">
| |
| zip (a:as) (b:bs) = if (as==[]) || (bs ==[]) -- || means 'or'
| |
| then [(a,b)]
| |
| else (a,b):(zip as bs)
| |
|
| |
| iterate f x = x:(iterate f (f x))</source>
| |
| | |
| To prove this, we can implement both using our generic unfold, <code>ana</code>, using a simple recursive routine:
| |
| <source lang="haskell">
| |
| zip2 = ana unsp fin
| |
| where
| |
| fin (as,bs) = (as==[]) || (bs ==[])
| |
| unsp ((a:as), (b:bs)) = ((a,b),(as,bs))
| |
| | |
| iterate2 f = ana (\a->(a,f a)) (\x->False) </source>
| |
| In a language like Haskell, even the abstract functions <code>fold</code>, <code>unfold</code> and <code>ana</code> are merely defined terms, as we have seen from the definitions given above.
| |
| | |
| == Anamorphisms in category theory ==
| |
| | |
| In [[category theory]], anamorphisms are the [[categorical dual]] of [[catamorphism]]s (and catamorphisms are the categorical dual of anamorphisms).
| |
| | |
| That means the following.
| |
| Suppose (''A'', ''fin'') is a [[Initial algebra|final]] ''F''-[[coalgebra]] for some [[endofunctor]] ''F'' of some [[category (mathematics)|category]] into itself.
| |
| Thus, ''fin'' is a [[morphism]] from ''A'' to ''FA'', and since it is assumed to be final we know that whenever (''X'', ''f'') is another ''F''-coalgebra (a morphism ''f'' from ''X'' to ''FX''), there will be a unique [[homomorphism]] ''h'' from (''X'', ''f'') to (''A'', ''fin''), that is a morphism ''h'' from ''X'' to ''A'' such that ''fin '''.''' h = Fh '''.''' f''.
| |
| Then for each such ''f'' we denote by '''ana''' '''''f''''' that uniquely specified morphism ''h''.
| |
| | |
| In other words, we have the following defining relationship, given some fixed ''F'', ''A'', and ''fin'' as above:
| |
| | |
| *<math>h = \mathrm{ana}\ f</math>
| |
| *<math>fin\circ h = Fh \circ f</math>
| |
| | |
| === Notation ===
| |
| | |
| A notation for ana ''f'' found in the literature is <math>[\!(f)\!]</math>. The brackets used are known as '''lens brackets''', after which anamorphisms are sometimes referred to as ''lenses''.
| |
| | |
| == See also ==
| |
| | |
| * [[Catamorphism]]
| |
| * [[Hylomorphism (computer science)|Hylomorphism]]
| |
| * [[Paramorphism]]
| |
| * [[Apomorphism]]
| |
| * [[Morphism]]
| |
| | |
| == References ==
| |
| {{reflist}}
| |
| | |
| == External links ==
| |
| * [http://ulissesaraujo.wordpress.com/2009/04/08/anamorphisms-in-haskell/ Anamorphisms in Haskell]
| |
| | |
| [[Category:Category theory]]
| |
| [[Category:Recursion schemes]]
| |