| Copyright | © Frank Jung 2021-2023 |
|---|---|
| License | GPL-3 |
| Safe Haskell | Safe-Inferred |
| Language | Haskell2010 |
RecursionSchemes
Description
A collection of recursion scheme examples.
Examples
Anamorphism
Using a non-recursive coalgebra to create a ListF.
test = buildListF 4 show test "ConsF 4 (ConsF 3 (ConsF 2 (ConsF 1 NilF)))" λ> :t unFix test unFix test :: ListF Int (Fix (ListF Int)) λ> :t test test :: Fix (ListF Int)
Catamorphism
Using a non-recursive algebra to measure length of ListF entry, use a
catamorphism over the alegra to measure length of the entire ListF.
test :: Int a => Fix (ListF a) test = Fix (ConsF 4 (Fix (ConsF 3 (Fix (ConsF 2 (Fix (ConsF 1 (Fix NilF)))))))) lengthListF test 4
Paramorphism
The paramorphism examples come from "Making Sense of Recursion Patterns". A paramorphism is like a catamorphism, but it preserves the initial data structure.
References
Synopsis
- newtype Fix f = Fix {}
- data ListF a r
- data NatF r
- type Nat = Fix NatF
- type RAlgebra f a = Fix f -> f a -> a
- ana :: Functor f => (a -> f a) -> a -> Fix f
- cata :: Functor f => (f a -> a) -> Fix f -> a
- para :: Functor f => RAlgebra f a -> Fix f -> a
- para' :: (a -> [a] -> b -> b) -> b -> [a] -> b
- para'' :: (a -> [a] -> b -> b) -> b -> [a] -> b
- buildListF :: Int -> Fix (ListF Int)
- buildCoalg :: Int -> ListF Int Int
- lengthAlg :: ListF a Int -> Int
- lengthListF :: Fix (ListF a) -> Int
- lengthListF' :: Fix (ListF a) -> Int
- fromNat :: Nat -> Int
- toNat :: Int -> Nat
- insert :: Ord a => a -> [a] -> [a]
- insert' :: Ord a => a -> [a] -> [a]
- toList :: Fix (ListF a) -> [a]
- idx0 :: (Foldable t, Num b) => t a -> [b]
- idx1 :: (Foldable t, Num b) => t a -> [b]
- idx2 :: [b] -> [Integer]
- idx3 :: Foldable t => t a -> [Integer]
- idx4 :: [b] -> [Integer]
Data constructors
Generalised fixed point for any functor f.
Note that unFix (Fix x) == x
List Functor where r is the carrier type.
Natural numbers Functor.
type RAlgebra f a = Fix f -> f a -> a Source #
The code defines a type synonym RAlgebra that represents a recursive algebra for a functor f. An R-algebra is a function that takes a fixed point of a functor Fix f and a value of type f a, and returns a value of type a.
The Fix type is used to define recursive data structures in Haskell. It is a type constructor that takes a functor f as an argument and returns a fixed point of f. The Fix type is used to define recursive data structures by wrapping a value of type f (Fix f) in a Fix constructor.
The RAlgebra type synonym is used to define a function that takes a fixed point of a functor Fix f and a value of type f a, and returns a value of type a. This function is used to define recursive functions that operate on data structures defined using Fix.
The RAlgebra type synonym is a higher-order type that takes two type arguments: f, which is a functor, and a, which is the return type of the algebra. The RAlgebra type synonym is used to define recursive functions that operate on data structures defined using Fix.
Recursion schemes
para :: Functor f => RAlgebra f a -> Fix f -> a Source #
Paramorphism - improved consumption of a structure.
para' :: (a -> [a] -> b -> b) -> b -> [a] -> b Source #
Paramorphism where input list is the first parameter.
This comes from
Making Sense of Recursion Patterns
by Paul Bailes and Leighton Brough. It extends foldr by supplying to the
combining operation (op) the unprocessed list tail, in addition to the head
and the result of recursion on the tail as provided by foldr.
Sum a list:
>>>para' (const . (+)) 0 [1,2,3]6
Suffixes of a list:
>>>para' (const (:)) [] "abcd"["bcd","cd","d",""]
para'' :: (a -> [a] -> b -> b) -> b -> [a] -> b Source #
Paramorphism using foldr.
This comes from
Making Sense of Recursion Patterns
by Paul Bailes and Leighton Brough.
The following shows how to get a catamorphism from a paramorphism. In this example, we are calculating the sum of items from a list.
Sum a list:
>>>para'' (const . (+)) 0 [1,2,3]6
Suffixes of a list:
>>>para'' (\ _ xs xss -> xs : xss) [] "abcd"["bcd","cd","d",""]
>>>para'' (const (:)) [] "abcd"["bcd","cd","d",""]
Coalgebra's
buildListF :: Int -> Fix (ListF Int) Source #
Feed coalgebra to anamorphism. This will build a list.
>>>buildListF 4 :: Fix (ListF Int)ConsF 4 (ConsF 3 (ConsF 2 (ConsF 1 NilF)))
buildCoalg :: Int -> ListF Int Int Source #
Coalgebra is a non-recursive function to generate a ListF entry.
Algebra's
lengthListF :: Fix (ListF a) -> Int Source #
Length is a folding operation, i.e. a Catamorphism.
>>>(lengthListF . buildListF) 44
lengthListF' :: Fix (ListF a) -> Int Source #
Length using special case of paramorphism.
>>>lengthListF' (buildListF 4)4
Build a natural number from an interger.
>>>toNat 4SuccF (SuccF (SuccF (SuccF ZeroF)))
Utilities
insert :: Ord a => a -> [a] -> [a] Source #
Insert element into list at correct ordered position using foldr.
>>>insert 1 [2,3,4][1,2,3,4]
>>>insert 'c' "abde""abcde"
>>>insert 'f' "abcde""abcdef"
>>>insert 'o' "oa""ooa"
insert' :: Ord a => a -> [a] -> [a] Source #
Insert element into list at correct ordered position.
>>>insert' 1 [2,3,4][1,2,3,4]
>>>insert' 1 [][1]
>>>insert' 'c' "abde""abcde"
>>>insert' 'c' "abde" == "abcde"True
>>>insert' 'o' "oa""ooa"
idx1 :: (Foldable t, Num b) => t a -> [b] Source #
Alternate list indexing using foldr.
>>>idx1 "abcde"[0,1,2,3,4]