Недавно я наконец почувствовал, что понимаю катаморфизм. Я написал несколько о них в недавнем ответе, но вкратце я бы сказал, что катаморфизм для абстрактных тегов в процессе рекурсивного прохождения значения этого типа с шаблоном совпадения этого типа в одной функции для каждого конструктора, имеющего тип. Хотя я бы приветствовал любые исправления в этом вопросе или более длинную версию в ответе, указанном выше, я думаю, что у меня это более или менее, и это не вопрос этого вопроса, просто какой-то фон.
Как только я понял, что функции, которые вы передаете катаморфизму, точно соответствуют конструкторам типа, а аргументы этих функций также соответствуют типам полей этих конструкторов, все это внезапно кажется довольно механическим, и я не вижу где есть место для маневра для альтернативных реализаций.
Например, я просто составил этот глупый тип, без реальной концепции того, что его структура "означает", и вывел для него катаморфизм. Я не вижу другого способа, которым я мог бы определить общую цель для этого типа:
data X a b f = A Int b
| B
| C (f a) (X a b f)
| D a
xCata :: (Int -> b -> r)
-> r
-> (f a -> r -> r)
-> (a -> r)
-> X a b f
-> r
xCata a b c d v = case v of
A i x -> a i x
B -> b
C f x -> c f (xCata a b c d x)
D x -> d x
Мой вопрос в том, имеет ли каждый тип уникальный катаморфизм (до переупорядочения аргументов)? Или существуют контрпримеры: типы, для которых нельзя определить катаморфизм, или типы, для которых существуют два различных, но одинаково приемлемых катаморфизма? Если нет контрпримеров (т.е. Катаморфизм для типа является уникальным и тривиально выводимым), можно ли получить GHC для получения какой-то спецификации для меня, которая автоматически выполняет эту drudgework?