@hackage recursion-schemes-ext0.2.1.0
Amateur addenda to recursion-schemes
Installation
Dependencies (6)
- base >4.9 && <4.11
- composition-prelude <1.2.0.0
- deepseq
- lens
- recursion-schemes >=5.0
- template-haskell Show all…
Dependents (2)
@hackage/acme-everything, @hackage/madlang
Package Flags
development
(off by default)
Enable `-Werror`
recursion-schemes-ext
This adds several functions to
recursion-schemes,
including a cataM.
Pitch
Monadic Functions
This package provides cataM, anaM, and hyloM. That means you can have
(co)algebras that return a monadic value.
Dendromorphisms etc.
Let's say you want to collapse a syntax tree. Suppose further that it's a relatively involved syntax tree, and you have some data types that encapsulate others. Here's a simple-minded example, where we collapse using traditional recursion schemes:
-- | We call our co-dependent data types 'Ernie' and 'Bert'. They represent mutually recursive
data Bert = Bert Ernie
| Num Integer
| String String
| Add Bert Bert
data Ernie = Ernie Bert
| Multiply Ernie Ernie
| List [Ernie]
makeBaseFunctor ''Ernie
makeBaseFunctor ''Bert
collapseErnieSyntaxTree :: (Recursive Ernie) => Ernie -> Ernie
collapseErnieSyntaxTree = cata algebra
where algebra (ErnieF e) = Ernie $ collapseBertSyntaxTree' e
algebra (MultiplyF (Ernie (Num i)) (Ernie (Num j))) = Ernie . Num $ i * j
algebra x = embed x
collapseBertSyntaxTree :: (Recursive Bert) => Bert -> Bert
collapseBertSyntaxTree = cata algebra
where algebra (BertF e) = Bert $ collapseErnieSyntaxTree' e
algebra (AddF (Num i) (Num j)) = Num $ i + j
algebra x = embed x
Contrast this to the solution using a dendromorphism, viz.
-- | We call our co-dependent data types 'Ernie' and 'Bert'. They represent mutually recursive
data Bert = Bert Ernie
| Num Integer
| String String
| Add Bert Bert
data Ernie = Ernie Bert
| Multiply Ernie Ernie
| List [Ernie]
makeBaseFunctor ''Ernie
makeBaseFunctor ''Bert
bertLens :: Lens' Bert Bert
bertLens = ...
ernieLens :: Lens' Ernie Ernie
ernieLens = ...
bertAlgebra :: BertF Bert -> Bert
bertAlgebra (AddF (Num i) (Num j)) = Num $ i + j
bertAlgebra x = embed x
ernieAlgebra :: ErnieF Ernie -> Ernie
ernieAlgebra (MultiplyF (Ernie (Num i)) (Ernie (Num j))) = Ernie . Num $ i * j
ernieAlgebra x = embed x
collapseErnieSyntaxTree :: (Recursive Ernie) => Ernie -> Ernie
collapseErnieSyntaxTree = dendro (dummy :: Bert) ernieLens bertAlgebra ernieAlgebra
collapseBertSyntaxTree :: (Recursive Bert) => Bert -> Bert
collapseBertSyntaxTree = dendro (dummy :: Ernie) bertLens ernieAlgebra bertAlgebra
Anti-Pitch
This library is experimental! The API of dendromorphisms and chemamorphisms in particular is subject to change.