1

I'm told the following functions are equivalent in power

hylo :: Functor f => (f b -> b) -> (a -> f a) -> a -> b
hylo f g = h where h = f . fmap h . g

hyloM :: (Traversable g, Monad m) => (g b -> m b) -> (a -> m (g a)) -> a -> m b
hyloM f g = h where h = f <=< traverse h <=< g

For the life of me, though, I can't figure out how to demonstrate this. Setting Monad to Identity in hyloM gets pretty much the right thing, but g is Traversable not Functor, and I have tried a number of approaches to go from hylo to hyloM with no success.

Are these isomorphic, or at least similar in power? If so, how do I evidence that?

Julian Birch
  • 2,605
  • 1
  • 21
  • 36
  • 1
    What does it mean for them to be equivalent in power, if they work on different types? The only meaning I could understand would be "hylo can be implemented in terms of hyloM, and vice versa, using some translation between the types involved". – amalloy Nov 30 '18 at 00:07
  • Exactly that. I think the answer given plus the comments exhibits the "nearly isomorphism". It would be nice if they were exactly isomorphic, but I think hyloM needs modification for that. – Julian Birch Dec 01 '18 at 12:06

1 Answers1

3

You can define hyloM using hylo by instantiating f = Compose m g.

hyloM' :: (Traversable g, Monad m) => (g b -> m b) -> (a -> m (g a)) -> a -> m b
hyloM' f g = hylo (\(Compose mg) -> mg >>= sequence >>= f) (\a -> Compose (g a))

I'm not sure about the converse.

Li-yao Xia
  • 31,896
  • 2
  • 33
  • 56
  • 2
    I think the converse is either trivial (making `m ~ Identity`, if you don't mind adding the `Traversable` constraint) or impossible (if you do mind adding the constraint). – duplode Nov 30 '18 at 02:17
  • 1
    Yeah, if you parameterise by the traversal function it's easy enough to swap f Identity to Identity f though, so maybe it's only equivalent to "gHyloM" – Julian Birch Dec 01 '18 at 12:04