Демонстрация взаимосвязи между hylo и hyloM

Мне сказали, что следующие функции эквивалентны по мощности

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

Однако, убей меня, я не могу понять, как это продемонстрировать. Установка Monad в Identity в hyloM — это почти правильно, но g — это Traversable, а не Functor, и я пробовал несколько подходов для перехода от hylo к hyloM, но безуспешно.

Являются ли они изоморфными или, по крайней мере, схожими по силе? Если да, то как мне это доказать?


person Julian Birch    schedule 29.11.2018    source источник
comment
Что значит для них равноценность по мощности, если они работают на разных типах? Единственное значение, которое я мог понять, это то, что hylo можно реализовать с точки зрения hyloM и наоборот, используя некоторый перевод между задействованными типами.   -  person amalloy    schedule 30.11.2018
comment
Именно это. Я думаю, что данный ответ плюс комментарии демонстрируют почти изоморфизм. Было бы хорошо, если бы они были точно изоморфны, но я думаю, что для этого hyloM нуждается в модификации.   -  person Julian Birch    schedule 01.12.2018


Ответы (1)


Вы можете определить hyloM, используя hylo, создав экземпляр 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))

Я не уверен в обратном.

person Li-yao Xia    schedule 30.11.2018
comment
Я думаю, что обратное либо тривиально (создание m ~ Identity, если вы не возражаете против добавления ограничения Traversable), либо невозможно (если вы не возражаете против добавления ограничения). - person duplode; 30.11.2018
comment
Да, если вы параметризуете функцию обхода, достаточно легко поменять местами f Identity на Identity f, так что, возможно, это эквивалентно только gHyloM - person Julian Birch; 01.12.2018