HORIZON HASKELLDocslts/ghc-9.10.x248f8f02026-10-05Search names, modules, packages, or :: a typeCtrl K

GHC 9.10.3 · lts/ghc-9.10.x · 248f8f0 · 2026-10-05

Moduledata-fix-0.3.4Haskell2010

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.

Example1 expression
data ListF a b = Nil | Cons a b deriving (Show, Functor)

The list is then a fixed point of ListF

Example1 expression
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.

Example1 expression
:{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.

  • 3 types
  • 26 values
  • Packagedata-fix-0.3.4
  • Exports29
  • LanguageHaskell2010
  • LicenceBSD-3-Clause
  • SourceFix.hs

Fix

7 declarations
newtypenewtype Fix (f :: Type -> Type)
#

A fix-point type.

Constructors

Instances9Eq, Data, Ord, Read, Show, Generic, …
valuefoldFix :: Functor f => (f a -> a) -> Fix f -> a
#

Fold Fix.

Example2 expressions
let fp = unfoldFix (\i -> if i < 4 then Cons i (i + 1) else Nil) (0 :: Int)foldFix (elimListF 0 (+)) fp6
valueunfoldFix :: Functor f => (a -> f a) -> a -> Fix f
#

Unfold Fix.

Example1 expression
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))))))))
valuewrapFix :: f (Fix f) -> Fix f
#

Wrap Fix.

Example2 expressions
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))))))))
valueunwrapFix :: Fix f -> f (Fix f)
#

Unwrap Fix.

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

Mu - least fixed point

6 declarations
newtypenewtype Mu (f :: Type -> Type)
#

Least fixed point. Efficient folding.

Constructors

  • Mu
    • unMu :: forall a. (f a -> a) -> a
Instances4Eq, Ord, Read, Show
valuehoistMu :: (forall a. f a -> g a) -> Mu f -> Mu g
#

Change base functor in Mu.

valuefoldMu :: (f a -> a) -> Mu f -> a
#

Fold Mu.

Example2 expressions
let mu = unfoldMu (\i -> if i < 4 then Cons i (i + 1) else Nil) (0 :: Int)foldMu (elimListF 0 (+)) mu6
valueunfoldMu :: Functor f => (a -> f a) -> a -> Mu f
#

Unfold Mu.

Example1 expression
unfoldMu (\i -> if i < 4 then Cons i (i + 1) else Nil) (0 :: Int)unfoldMu unFix (Fix (Cons 0 (Fix (Cons 1 (Fix (Cons 2 (Fix (Cons 3 (Fix Nil)))))))))
valuewrapMu :: Functor f => f (Mu f) -> Mu f
#

Wrap Mu.

Example2 expressions
let x = unfoldMu (\i -> if i < 3 then Cons i (i + 1) else Nil) (0 :: Int)wrapMu (Cons 10 x)unfoldMu unFix (Fix (Cons 10 (Fix (Cons 0 (Fix (Cons 1 (Fix (Cons 2 (Fix Nil)))))))))
valueunwrapMu :: Functor f => Mu f -> f (Mu f)
#

Unwrap Mu.

Example2 expressions
let x = unfoldMu (\i -> if i < 3 then Cons i (i + 1) else Nil) (0 :: Int)unwrapMu xCons 0 (unfoldMu unFix (Fix (Cons 1 (Fix (Cons 2 (Fix Nil))))))

Nu - greatest fixed point

6 declarations
datadata Nu (f :: Type -> Type)
#

Greatest fixed point. Efficient unfolding.

Constructors

  • forall a. Nu (a -> f a) a
Instances4Eq, Ord, Read, Show
valuehoistNu :: (forall a. f a -> g a) -> Nu f -> Nu g
#

Change base functor in Nu.

valuefoldNu :: Functor f => (f a -> a) -> Nu f -> a
#

Fold Nu.

Example2 expressions
let nu = unfoldNu (\i -> if i < 4 then Cons i (i + 1) else Nil) (0 :: Int)foldNu (elimListF 0 (+)) nu6
valueunfoldNu :: (a -> f a) -> a -> Nu f
#

Unfold Nu.

Example1 expression
unfoldNu (\i -> if i < 4 then Cons i (i + 1) else Nil) (0 :: Int)unfoldNu unFix (Fix (Cons 0 (Fix (Cons 1 (Fix (Cons 2 (Fix (Cons 3 (Fix Nil)))))))))
valuewrapNu :: Functor f => f (Nu f) -> Nu f
#

Wrap Nu.

Example2 expressions
let x = unfoldNu (\i -> if i < 3 then Cons i (i + 1) else Nil) (0 :: Int)wrapNu (Cons 10 x)unfoldNu unFix (Fix (Cons 10 (Fix (Cons 0 (Fix (Cons 1 (Fix (Cons 2 (Fix Nil)))))))))
valueunwrapNu :: Functor f => Nu f -> f (Nu f)
#

Unwrap Nu.

Example2 expressions
let x = unfoldNu (\i -> if i < 3 then Cons i (i + 1) else Nil) (0 :: Int)unwrapNu xCons 0 (unfoldNu unFix (Fix (Cons 1 (Fix (Cons 2 (Fix Nil))))))

Refolding

1 declaration
valuerefold :: Functor f => (f b -> b) -> (a -> f a) -> a -> b
#

Refold one recursive type into another, one layer at the time.

Monadic variants

3 declarations

Deprecated aliases

6 declarations
valuecata :: Functor f => (f a -> a) -> Fix f -> a
#

Deprecated. Use foldFix

Catamorphism or generic function fold.

valueana :: Functor f => (a -> f a) -> a -> Fix f
#

Deprecated. Use unfoldFix

Anamorphism or generic function unfold.

valuehylo :: Functor f => (f b -> b) -> (a -> f a) -> a -> b
#

Deprecated. Use refold

Hylomorphism is anamorphism followed by catamorphism.

valueanaM :: (Monad m, Traversable t) => (a -> m (t a)) -> a -> m (Fix t)
#

Deprecated. Use unfoldFixM

Monadic anamorphism.

valuehyloM
  1. :: (Monad m, Traversable t)
  2. => t b -> m b
  3. -> a -> m (t a)
  4. -> a
  5. -> m b
#

Deprecated. Use refoldM

Monadic hylomorphism.