fix package:data-fix

Fixed points of a functor. Type f should be a Functor if you want to use simple recursion schemes or Traversable if you want to use monadic recursion schemes. This style allows you to express recursive functions in non-recursive manner. You can imagine that a non-recursive function holds values of the previous iteration. An example: First we define a base functor. The arguments b are recursion points.
>>> data ListF a b = Nil | Cons a b deriving (Show, Functor)
The list is then a fixed point of ListF
>>> type List a = Fix (ListF a)
We can write length function. Note that the function we give to foldFix is not recursive. Instead the results of recursive calls are in b positions, and we need to deal only with one layer of the structure.
>>> :{
let length :: List a -> Int
length = foldFix $ \x -> case x of
Nil      -> 0
Cons _ n -> n + 1
:}
If you already have recursive type, like '[Int]', you can first convert it to `Fix (ListF a)` and then foldFix. Alternatively you can use recursion-schemes combinators which work directly on recursive types.
A fix-point type.
Fixpoint data types Fixpoint types and recursion schemes. If you define your AST as fixpoint type, you get fold and unfold operations for free. Thanks for contribution to: Matej Kollar, Herbert Valerio Riedel
Fold Fix.
>>> let fp = unfoldFix (\i -> if i < 4 then Cons i (i + 1) else Nil) (0 :: Int)

>>> foldFix (elimListF 0 (+)) fp
6
Monadic foldFix.
Change base functor in Fix.
Like hoistFix but fmapping over g.
Unfold Fix.
>>> unfoldFix (\i -> if i < 4 then Cons i (i + 1) else Nil) (0 :: Int)
Fix (Cons 0 (Fix (Cons 1 (Fix (Cons 2 (Fix (Cons 3 (Fix Nil))))))))
Monadic anamorphism.
Unwrap Fix.
>>> let x = unfoldFix (\i -> if i < 3 then Cons i (i + 1) else Nil) (0 :: Int)

>>> unwrapFix x
Cons 0 (Fix (Cons 1 (Fix (Cons 2 (Fix Nil)))))
Wrap Fix.
>>> let x = unfoldFix (\i -> if i < 3 then Cons i (i + 1) else Nil) (0 :: Int)

>>> wrapFix (Cons 10 x)
Fix (Cons 10 (Fix (Cons 0 (Fix (Cons 1 (Fix (Cons 2 (Fix Nil))))))))