I am trying to wrap my head around the concept of anamorphism.
In functional programming, an anamorphism is a generalization of the concept of unfolds on lists. Formally, anamorphisms are generic functions that can corecursively construct a result of a certain type and which is parameterized by functions that determine the next single step of the construction.
Its dual, catamorphism, is nicely described in this post: What is a catamorphism and can it be implemented in C# 3.0?.
A nice example of catamorphic behavior in C# is the LINQ's Aggregate method.
What would an anamorphic equivalent be? Is it correct to think of a pseudo-random number generator Random as an anamorphic construct or should the process of unfolding always include an accumulator function like the one below (code snippet taken from Intro to Rx)?
IEnumerable<T> Unfold<T>(T seed, Func<T, T> accumulator)
{
var nextValue = seed;
while (true)
{
yield return nextValue;
nextValue = accumulator(nextValue);
}
}
LINQ's Aggregate method has the signature
So the corresponding unfolding would be
In pure functional programming, folding and unfolding must include a deterministic function. For C#'s
System.Random
, this is true if you consider its deterministic internals as an implicit function, as you suggest. One could recreate this precise PRNG usingUnfold
, so it may not use folding but be functionally and semantically equivalent to a fold.The two folding and unfolding of lists above are special cases of the more general folding of lists:
In LINQ, this generality is present in other combinators such as
Select
.As Brian's answer to the question What is a catamorphism and can it be implemented in C# 3.0?:
Likewise, one may construct anamorphisms on binary trees in C#:
Here is a rather silly example of how to build the Collatz numbers in this XKCD strip:
Here is a heteronormative example of building a family tree:
I didn't run any of the code above so there may be errors.