В чем разница между Fix, Mu и Nu в пакете схемы рекурсии Эда Кметта

В пакете recursion-scheme Эда Кметта есть три объявления:

newtype Fix f = Fix (f (Fix f))

newtype Mu f = Mu (forall a. (f a -> a) -> a)

data Nu f where 
  Nu :: (a -> f a) -> a -> Nu f

В чем разница между этими тремя типами данных?


person hgiesel    schedule 09.08.2017    source источник
comment
Я не очень хорошо разбираюсь в теории, но полагаю, что для более надежных языков Mu — наименьшая фиксированная точка, а Nu — наибольшая фиксированная точка. В Haskell все эти три должны быть эквивалентны (я полагаю). Обратите внимание, что реализовать cata для Mu и ana для Nu очень просто.   -  person dfeuer    schedule 09.08.2017
comment
Попробуйте решить эту ката codewars.com/kata/folding-through -a-fixed-point/haskell   -  person xgrommx    schedule 11.08.2017


Ответы (1)


Mu представляет рекурсивный тип как его свертку, а Nu представляет его как его развертывание. В Haskell они изоморфны и представляют собой разные способы представления одного и того же типа. Если вы сделаете вид, что в Haskell нет произвольной рекурсии, различие между этими типами станет более интересным: Mu f — это наименьшая (начальная) фиксированная точка f, а Nu f — его наибольшая (конечная) фиксированная точка.

Неподвижная точка f является типом T изоморфизмом между T и f T, то есть парой обратных функций in :: f T -> T, out :: T -> f T. Тип Fix просто использует встроенную в Haskell рекурсию типов для прямого объявления изоморфизма. Но вы можете реализовать вход/выход как для Mu, так и для Nu.

В качестве конкретного примера представьте на мгновение, что вы не можете записывать рекурсивные значения. Жители Mu Maybe , то есть значения :: forall r. (Maybe r -> r) -> r, являются натуральными, {0, 1, 2, ...}; жители Nu Maybe, т. е. значения :: exists x. (x, x -> Maybe x), являются сонатуральными {0, 1, 2, ..., ∞}. Подумайте о возможных значениях этих типов, чтобы понять, почему Nu Maybe имеет лишнего обитателя.

Если вы хотите получить некоторую интуицию для этих типов, может быть забавным упражнением реализовать следующее без рекурсии (примерно в порядке возрастания сложности):

  • zeroMu :: Mu Maybe, succMu :: Mu Maybe -> Mu Maybe
  • zeroNu :: Nu Maybe, succNu :: Nu Maybe -> Nu Maybe, inftyNu :: Nu Maybe
  • muTofix :: Mu f -> Fix f, fixToNu :: Fix f -> Nu f
  • inMu :: f (Mu f) -> Mu f, outMu :: Mu f -> f (Mu f)
  • inNu :: f (Nu f) -> Nu f, outNu :: Nu f -> f (Nu f)

Вы также можете попробовать реализовать их, но они требуют рекурсии:

  • nuToFix :: Nu f -> Fix f, fixToMu :: Fix f -> Mu f

Mu f — наименьшая фиксированная точка, а Nu f — наибольшая, поэтому написать функцию :: Mu f -> Nu f очень просто, а написать функцию :: Nu f -> Mu f сложно; это как плыть против течения.

(В какой-то момент я собирался написать более подробное объяснение этих типов, но оно может оказаться слишком длинным для такого формата.)

person shachaf    schedule 09.08.2017
comment
Отличное объяснение, спасибо! Есть ли источники (статьи/документы/книги), которые объясняют это еще более подробно? Например, аналоги для фиксированных точек на уровне терминов и почему Nu (как представление рекурсивного типа в виде его свертки) является наименьшей фиксированной точкой на уровне типов. Существуют также важные связи между LFP и исходными алгебрами, а также между GFP и терминальной коалгеброй. - person Sergey Cherepanov; 01.09.2018
comment
Я уверен, что что-то упускаю, но Nu Maybe, кажется, имеет гораздо больше обитателей - по крайней мере, многих, которых Haskell с радостью проверяет. Например, Nu Just [], Nu Just "abcd", Nu (const Nothing) 42 кажутся правильно напечатанными. Что я делаю неправильно? - person B. Mehta; 02.09.2018
comment
Ждать. Сонатуральные числа? Это вещь? - person paulotorrens; 03.09.2018
comment
Сергей Черепанов: Я не знаю ни одного навскидку, хотя вот доказательство инициализации с использованием параметризации. Связь между начальными алгебрами и начальными неподвижными точками иногда называют леммой Ламбека. Б. Мехта: Точно так же, как id :: forall a. a -> a не может различать разные входные данные, внешний мир не может различать Nu Just [] и Nu Just 0. paulotorrens: По крайней мере, это идиоматическое название для этого типа, одноточечная компактификация натуральных чисел, по этой причине. - person shachaf; 11.09.2018
comment
Обновлена ​​ссылка для подтверждения подлинности. - person shachaf; 18.09.2018
comment
Спасибо за интересное упражнение! Я загрузил свой ответ здесь, если кому-то интересно: gist.github.com/inamiy/7488380da6001cb0f778b59d9f7230cd - person inamiy; 07.07.2020