packages feed

recursion 2.0.0.0 → 2.1.0.0

raw patch · 3 files changed

+111/−62 lines, 3 files

Files

CHANGELOG.md view
@@ -1,5 +1,11 @@ # recursion +## 2.1.0.0++* Add `scolioM`, `scolioM'`, `paraM`, `microM`, `mutuM`, `mutuM'`, `elgotM`, and+`coelgotM`+* Rename `dicata` to `scolio`+ ## 2.0.0.0  * Add `zygoM'`, the second monadic zygomorphism
recursion.cabal view
@@ -1,39 +1,41 @@-cabal-version:      1.18-name:               recursion-version:            2.0.0.0-license:            BSD3-license-file:       LICENSE-copyright:          Copyright: (c) 2018 Vanessa McHale-maintainer:         vanessa.mchale@iohk.io-author:             Vanessa McHale-bug-reports:        https://hub.darcs.net/vmchale/recursion/issues-synopsis:           A recursion schemes library for GHC.+cabal-version: 1.18+name: recursion+version: 2.1.0.0+license: BSD3+license-file: LICENSE+copyright: Copyright: (c) 2018 Vanessa McHale+maintainer: vanessa.mchale@iohk.io+author: Vanessa McHale+bug-reports: https://hub.darcs.net/vmchale/recursion/issues+synopsis: A recursion schemes library for GHC. description:     A performant recursion schemes library for Haskell with minimal dependencies-category:           Control, Recursion-build-type:         Simple-extra-source-files: cabal.project.local-extra-doc-files:-    README.md-    CHANGELOG.md+category: Control, Recursion+build-type: Simple+extra-source-files:+    cabal.project.local+extra-doc-files: README.md+                 CHANGELOG.md  source-repository head-    type:     darcs+    type: darcs     location: https://hub.darcs.net/vmchale/recursion  flag development-    description: Enable `-Werror`-    default:     False-    manual:      True+    description:+        Enable `-Werror`+    default: False+    manual: True  library-    exposed-modules:  Control.Recursion-    hs-source-dirs:   src+    exposed-modules:+        Control.Recursion+    hs-source-dirs: src     default-language: Haskell2010-    other-extensions:-        DeriveFunctor FlexibleContexts ExistentialQuantification RankNTypes-        TypeFamilies DeriveFoldable DeriveTraversable-    ghc-options:      -Wall+    other-extensions: DeriveFunctor FlexibleContexts+                      ExistentialQuantification RankNTypes TypeFamilies DeriveFoldable+                      DeriveTraversable+    ghc-options: -Wall     build-depends:         base >=4.9 && <5,         composition-prelude -any@@ -42,9 +44,8 @@         ghc-options: -Werror      if impl(ghc >=8.0)-        ghc-options:-            -Wincomplete-uni-patterns -Wincomplete-record-updates-            -Wredundant-constraints -Wnoncanonical-monad-instances+        ghc-options: -Wincomplete-uni-patterns -Wincomplete-record-updates+                     -Wredundant-constraints -Wnoncanonical-monad-instances      if impl(ghc >=8.4)         ghc-options: -Wmissing-export-lists
src/Control/Recursion.hs view
@@ -30,7 +30,7 @@     , micro     , meta     , meta'-    , dicata+    , scolio     , cata     , ana     -- * Mendler-style recursion schemes@@ -42,6 +42,14 @@     , hyloM     , zygoM     , zygoM'+    , scolioM+    , scolioM'+    , coelgotM+    , elgotM+    , paraM+    , mutuM+    , mutuM'+    , microM     -- * Helper functions     , lambek     , colambek@@ -86,6 +94,7 @@  newtype Fix f = Fix { unFix :: f (Fix f) } +-- Ν, Μ data Nu f = forall a. Nu (a -> f a) a  newtype Mu f = Mu (forall a. (f a -> a) -> a)@@ -146,7 +155,10 @@ instance Functor f => Corecursive (Fix f) where     embed = Fix --- | Catamorphism. Folds a structure. (see [here](http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.41.125&rep=rep1&type=pdf))+eitherM :: Monad m => (a -> m c) -> (b -> m c) -> m (Either a b) -> m c+eitherM l r = (either l r =<<)++-- | Catamorφsm. Folds a structure. (see [here](http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.41.125&rep=rep1&type=pdf)) cata :: (Recursive t) => (Base t a -> a) -> t -> a cata f = c where c = f . fmap c . project {-# NOINLINE [0] cata #-}@@ -155,7 +167,7 @@   "cata/Mu" forall f (g :: forall a. (f a -> a) -> a). cata f (Mu g) = g f;      #-} --- | Anamorphism, meant to build up a structure recursively.+-- | Anamorφsm, meant to build up a structure recursively. ana :: (Corecursive t) => (a -> Base t a) -> a -> t ana g = a where a = embed . fmap a . g {-# NOINLINE [0] ana #-}@@ -165,7 +177,7 @@       #-}  -- | Base functor for a list of type @[a]@.--- | Hylomorphism; fold a structure while buildiung it up.+-- | Hylomorφsm; fold a structure while buildiung it up. hylo :: Functor f => (f b -> b) -> (a -> f a) -> a -> b hylo f g = h where h = f . fmap h . g {-# NOINLINE [0] hylo #-}@@ -174,85 +186,115 @@   "ana/cata/hylo"  forall f g x. cata f (ana g x) = hylo f g x;      #-} +zipA :: (Applicative f) => f a -> f b -> f (a, b)+zipA x y = (,) <$> x <*> y++zipM :: (Monad m) => m a -> m b -> m (a, b)+zipM x y = do { a <- y; b <- x; pure (b, a) }+ cataM :: (Recursive t, Traversable (Base t), Monad m) => (Base t a -> m a) -> t -> m a cataM f = c where c = f <=< (traverse c . project) +paraM :: (Recursive t, Corecursive t, Traversable (Base t), Monad m) => (Base t (t, a) -> m a) -> t -> m a+paraM f = fmap snd . cataM (\x -> (,) (embed (fmap fst x)) <$> f x)+ zygoM :: (Recursive t, Traversable (Base t), Monad m) => (Base t b -> m b) -> (Base t (b, a) -> m a) -> t -> m a-zygoM f g = fmap snd . cataM (\x -> (,) <$> f (fmap fst x) <*> g x)+zygoM f g = fmap snd . cataM (\x -> zipA (f (fmap fst x)) (g x))  zygoM' :: (Recursive t, Traversable (Base t), Monad m) => (Base t b -> m b) -> (Base t (b, a) -> m a) -> t -> m a-zygoM' f g = fmap snd . cataM (\x -> do { a <- g x; b <- f (fmap fst x); pure (b, a) })+zygoM' f g = fmap snd . cataM (\x -> zipM (f (fmap fst x)) (g x)) +scolioM :: (Recursive t, Traversable (Base t), Monad m) => (Base t (t, a) -> m t) -> (Base t (t, a) -> m a) -> t -> m a+scolioM f g = fmap snd . cataM (\x -> zipA (f x) (g x))++scolioM' :: (Recursive t, Traversable (Base t), Monad m) => (Base t (t, a) -> m t) -> (Base t (t, a) -> m a) -> t -> m a+scolioM' f g = fmap snd . cataM (\x -> zipM (f x) (g x))+ anaM :: (Corecursive t, Traversable (Base t), Monad m) => (a -> m (Base t a)) -> a -> m t anaM f = a where a = (fmap embed . traverse a) <=< f  hyloM :: (Traversable f, Monad m) => (f b -> m b) -> (a -> m (f a)) -> a -> m b hyloM f g = h where h = f <=< traverse h <=< g +elgotM :: (Traversable f, Monad m) => (f a -> m a) -> (b -> m (Either a (f b))) -> b -> m a+elgotM φ ψ = h where h = eitherM pure (φ <=< traverse h) . ψ++microM :: (Corecursive a, Traversable (Base a), Monad m) => (b -> m (Either a (Base a b))) -> b -> m a+microM = elgotM (pure . embed)++coelgotM :: (Traversable f, Monad m) => ((a, f b) -> m b) -> (a -> m (f a)) -> a -> m b+coelgotM φ ψ = h where h = φ <=< (\x -> (,) x <$> (traverse h <=< ψ) x)+ lambek :: (Recursive t, Corecursive t) => (t -> Base t t) lambek = cata (fmap embed)  colambek :: (Recursive t, Corecursive t) => (Base t t -> t) colambek = ana (fmap project) --- | Prepromorphism. Fold a structure while applying a natural transformation at each step.+-- | Prepromorφsm. Fold a structure while applying a natural transformation at each step. prepro :: (Recursive t, Corecursive t) => (Base t t -> Base t t) -> (Base t a -> a) -> t -> a prepro e f = c     where c = f . fmap (c . cata (embed . e)) . project --- | Postpromorphism. Build up a structure, applying a natural transformation along the way.+-- | Postpromorφsm. Build up a structure, applying a natural transformation along the way. postpro :: (Recursive t, Corecursive t) => (Base t t -> Base t t) -> (a -> Base t a) -> a -> t postpro e g = a'     where a' = embed . fmap (ana (e . project) . a') . g --- | A mutumorphism.+-- | A mutumorφsm. mutu :: (Recursive t) => (Base t (a, a) -> a) -> (Base t (a, a) -> a) -> t -> a-mutu f g =  snd . cata (f &&& g)+mutu f g = snd . cata (f &&& g) --- | Catamorphism collapsing along two data types simultaneously. Basically a fancy zygomorphism.-dicata :: (Recursive t) => (Base t (a, t) -> a) -> (Base t (a, t) -> t) -> t -> a-dicata = fst .** (cata .* (&&&))+mutuM :: (Recursive t, Traversable (Base t), Monad m) => (Base t (a, a) -> m a) -> (Base t (a, a) -> m a) -> t -> m a+mutuM f g = h where h = fmap snd . cataM (\x -> zipA (f x) (g x)) --- | Zygomorphism (see [here](http://www.iis.sinica.edu.tw/~scm/pub/mds.pdf) for a neat example)+mutuM' :: (Recursive t, Traversable (Base t), Monad m) => (Base t (a, a) -> m a) -> (Base t (a, a) -> m a) -> t -> m a+mutuM' f g = h where h = fmap snd . cataM (\x -> zipM (f x) (g x))++-- | Catamorφsm collaψng along two data types simultaneously.+scolio :: (Recursive t) => (Base t (a, t) -> a) -> (Base t (a, t) -> t) -> t -> a+scolio = fst .** (cata .* (&&&))++-- | Zygomorφsm (see [here](http://www.iis.sinica.edu.tw/~scm/pub/mds.pdf) for a neat example) zygo :: (Recursive t) => (Base t b -> b) -> (Base t (b, a) -> a) -> t -> a-zygo f g = snd . cata (((,) . f . fmap fst) <*> g)+zygo f g = snd . cata (\x -> (f (fmap fst x), g x)) --- | Paramorphism+-- | Paramorφsm para :: (Recursive t, Corecursive t) => (Base t (t, a) -> a) -> t -> a-para f = snd . cata (((,) . embed . fmap fst) <*> f)+para f = snd . cata (\x -> (embed (fmap fst x), f x)) --- | Gibbons' metamorphism. Tear down a structure, transform it, and then build up a new structure+-- | Gibbons' metamorφsm. Tear down a structure, transform it, and then build up a new structure meta :: (Corecursive t', Recursive t) => (a -> Base t' a) -> (b -> a) -> (Base t b -> b) -> t -> t' meta f e g = ana f . e . cata g --- | Erwig's metamorphism. Essentially a hylomorphism with a natural+-- | Erwig's metamorφsm. Essentially a hylomorφsm with a natural -- transformation in between. This allows us to use more than one functor in a--- hylomorphism.+-- hylomorφsm. meta' :: (Functor g) => (f a -> a) -> (forall c. g c -> f c) -> (b -> g b) -> b -> a meta' h e k = g     where g = h . e . fmap g . k --- | Mendler's catamorphism+-- | Mendler's catamorφsm mcata :: (forall y. ((y -> c) -> f y -> c)) -> Fix f -> c-mcata psi = mc where mc = psi mc . unFix+mcata ψ = mc where mc = ψ mc . unFix --- | Mendler's histomorphism+-- | Mendler's histomorφsm mhisto :: (forall y. ((y -> c) -> (y -> f y) -> f y -> c)) -> Fix f -> c-mhisto psi = mh where mh = psi mh unFix . unFix+mhisto ψ = mh where mh = ψ mh unFix . unFix  -- | Elgot algebra (see [this paper](https://arxiv.org/abs/cs/0609040)) elgot :: Functor f => (f a -> a) -> (b -> Either a (f b)) -> b -> a-elgot phi psi = h where h = either id (phi . fmap h) . psi+elgot φ ψ = h where h = either id (φ . fmap h) . ψ --- | Anamorphism allowing shortcuts. Compare 'apo'+-- | Anamorφsm allowing shortcuts. Compare 'apo' micro :: (Corecursive a) => (b -> Either a (Base a b)) -> b -> a micro = elgot embed --- | Elgot coalgebra+-- | Co-(Elgot algebra) coelgot :: Functor f => ((a, f b) -> b) -> (a -> f a) -> a -> b-coelgot phi psi = h where h = phi . ((,) <*> (fmap h . psi))+coelgot φ ψ = h where h = φ . (\x -> (x, fmap h . ψ $ x)) --- | Apomorphism. Compare 'micro'.+-- | Apomorφsm. Compare 'micro'. apo :: (Corecursive t) => (a -> Base t (Either t a)) -> a -> t apo g = a where a = embed . fmap (either id a) . g @@ -264,17 +306,17 @@ {-# NOINLINE [0] hoist #-}  hoistMu :: (forall a. f a -> g a) -> Mu f -> Mu g-hoistMu eta (Mu f) = Mu (f . (. eta))+hoistMu η (Mu f) = Mu (f . (. η))  hoistNu :: (forall a. f a -> g a) -> Nu f -> Nu g-hoistNu n (Nu f x) = Nu (n . f) x+hoistNu ν (Nu f x) = Nu (ν . f) x  {-# RULES-  "hoist/hoistMu" forall (eta :: forall a. f a -> f a) (f :: forall a. (f a -> a) -> a). hoist eta (Mu f) = hoistMu eta (Mu f);+  "hoist/hoistMu" forall (η :: forall a. f a -> f a) (f :: forall a. (f a -> a) -> a). hoist η (Mu f) = hoistMu η (Mu f);      #-}  {-# RULES-  "hoist/hoistNu" forall (eta :: forall a. f a -> f a) (f :: a -> f a) x. hoist eta (Nu f x) = hoistNu eta (Nu f x);+  "hoist/hoistNu" forall (η :: forall a. f a -> f a) (f :: a -> f a) x. hoist η (Nu f x) = hoistNu η (Nu f x);      #-}  refix :: (Recursive s, Corecursive t, Base s ~ Base t) => s -> t