Suggestion: Add monadic variants of various ...morphism functions. #3

Closed
ppetr opened this Issue Dec 7, 2012 · 6 comments

Comments

Projects
None yet
4 participants
Collaborator

ppetr commented Dec 7, 2012

I don't know if it's a good idea and if it isn't actually contained in some other generalized functions you already have, but I feel such monadic functions could be often useful:

-- | A monadic catamorphism.
cataM
  :: (Foldable t, T.Traversable (Base t), Monad m)
  => (Base t a -> m a) -- ^ a monadic (Base t)-algebra
  -> t                 -- ^ fixed point
  -> m a               -- ^ result
cataM f = c where c = f <=< T.mapM c <=< (return . project)

-- | A monadic anamorphism
anaM
  :: (Unfoldable t, T.Traversable (Base t), Monad m)
  => (a -> m (Base t a))        -- ^ a monadic (Base t)-coalgebra
  -> a                          -- ^ seed
  -> m t
anaM g = a where a = (return . embed) <=< T.mapM a <=< g

-- etc

If you like the idea, I can provide them.

this would be great, as well as examples of their use.

Or at implementation in arbitrary categories (of which the Kelsi category in one).

sboosali commented May 11, 2016 edited

I can't get it to work. There are at least two ways:

(the below might not typecheck)

  1. generalize Foldable and Functor
cataC
  :: (Category.Foldable t, Category.Functor (~>), f ~ Base t)
  => (f a ~> a)
  -> (t   ~> a)

cataC u = c where c = project Category.>>> Category.fmap c Category.>>> u

("Category.Foldable" and "Category.Functor" don't exist)

  1. use Arrow to inject functions (project and fmap)
cataC
  :: (Foldable t, Arrow (~>), f ~ Base t)
  => (f a -> a)
  -> (t   ~> a)

cataC u = c where c = arr (project Prelude.>>> fmap c) Category.>>> u

that's what the (. return) did in cataM.

will they be easy to work with?

On Wed, May 11, 2016 at 2:56 AM, Christopher King notifications@github.com
wrote:

Or at implementation in arbitrary categories (of which the Kelsi category
in one).


You are receiving this because you commented.
Reply to this email directly or view it on GitHub
#3 (comment)

(this message was composed with dictation: charitably interpret typos)Sam
Boosalis

Collaborator

phadej commented Jun 29, 2016

You can implement cataM using cata:

cataM :: ... => (Base t a     -> m a) -> t -> m a
cata  :: ... => (Base t b     -> b  ) -> t -> b
cata' :: ... => (Base t (m a) -> m a) -> t -> m a
cata' = cata
cataM f = (>>= f) . cata (traverse (>>= f))
λ Prelude Data.Functor.Foldable > let cataM f = (>>= f) . cata (traverse (>>= f))
λ Prelude Data.Functor.Foldable > :t cataM
cataM
  :: (Monad m, Traversable (Base t),
      Data.Functor.Foldable.Foldable t) =>
     (Base t b -> m b) -> t -> m b

IIRC, when I needed cataM I got away with cata by defining f to have traverse and >>= built-in.

The problem is e.g. Prim [a] is not Traversable atm, but you can do, yet it's easy to forget to >> previous actions:

> flip runState (0 :: Int) $ cata (\case { Nil -> return (); Cons _ x -> x >> modify' succ }) "foobar"
((),6)
Collaborator

phadej commented Jul 5, 2016

Added Traversable to Prim [a] in ca17aa9

phadej closed this Jul 5, 2016

Collaborator

phadej commented Jul 6, 2016

FWIW: https://hackage.haskell.org/package/unification-fd-0.10.0.1/docs/Data-Functor-Fixedpoint.html defines cataM, anaM and hyloM, yet I'm not sure if we want to made arbitrary choice in which order to sequence the effects,. Manual definition with non-monadic version is more powerful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment