Ответ 1
Канонический способ рекурсии с чистыми лямбда-выражениями - использовать комбинатор фиксированных точек, который является функцией со свойством
fixpoint f x = f (fixpoint f) x
Если предположить, что такой комбинатор существует, мы можем записать рекурсивную функцию как
factorial = fixpoint (\ff n -> if n == 1 then 1 else n * ff(n-1))
Единственная проблема заключается в том, что fixpoint
сам по-прежнему рекурсивный. В чистом исчислении лямбда существуют способы создания комбинаторов фиксированных точек, которые состоят только из лямбда, например классического "Y combinator":
fixpoint f = (\x -> f (x x)) (\x -> f (x x))
Но у нас все еще есть проблемы, потому что это определение не хорошо типизировано в соответствии с Haskell - и можно доказать, что нет способа написать хорошо подобранный комбинатор исправлений, используя только приложения лямбда и функции. Это можно сделать, используя вспомогательный тип данных для shoehorn в рекурсии определенного типа:
data Paradox a = Self (Paradox a -> a)
fixpoint f = let half (Self twin) = f (twin (Self twin))
in half (Self half)
(Обратите внимание, что если удаляются инъекции и проекции из однотипного типа данных, это как раз Y combinator!)