The foldr identity is
foldr (:) []
More generally, with folds you can either destroy structure and end up with a summary value or inject structure in such a way that you end up with the same output structure.
[Int] -> [Int]
or
[Int] -> Int
or
[Int] -> ?
I'm wondering if there a similar identity with unfoldr/l.
I know how to get
Int -> [Int]
with unfold/ana.
I'm looking for some kind of way to go from
Int -> Int
with a recursion scheme.
Taking a cue from your remark about factorials, we can note that natural numbers can be treated as a recursive data structure:
In terms of the recursion-schemes machinery, the corresponding base functor would be:
NatF, however, is isomorphic toMaybe. That being so, recursion-schemes conveniently makesMaybethe base functor of theNaturaltype from base. For instance, here is the type ofanaspecialised toNatural:We can use it to write the identity unfold for
Natural:The coalgebra we just gave to
anaisprojectforNatural,projectbeing the function that unwraps one layer of the recursive structure. In terms of the recursion-schemes vocabulary,ana projectis the identity unfold, andcata embedis the identity fold. (In particular,projectfor lists isunconsfromData.List, except that it is encoded withListFinstead ofMaybe.)By the way, the factorial function can be expressed as a paramorphism on naturals (as pointed out in the note at the end of this question). We can also implement that in terms of recursion-schemes:
paramakes available, at each recursive step, the rest of the structure to be folded (if we were folding a list, that would be its tail). In this case, I have called the value thus providedpredecbecause at then-th recursive step from bottom to toppredecisn - 1.Note that user11228628's hylomorphism is probably a more efficient implementation, if you happen to care about that. (I haven't benchmarked them, though.)