Я не утверждаю, что понимаю это вообще, но если это помогает кому-то ... тогда yippee.
Рассмотрите определение fix
. fix f = let x = f x in x
. Ошеломляющая часть состоит в том, что x
определяется как f x
. Но подумайте об этом на минуту.
x = f x
Так как X = F х, то мы можем подставить значение x
на правой стороне, что, верно? И поэтому ...
x = f . f $ x -- or x = f (f x)
x = f . f . f $ x -- or x = f (f (f x))
x = f . f . f . f . f . f . f . f . f . f . f $ x -- etc.
Так трюк для того, чтобы прекратить, f
должен генерировать какую-то структуру, так что позже f
может сопрягать образец, структура и прекращает рекурсию, фактически не заботясь о полное «значение» его параметра (?)
Если, конечно, вы не хотите делать что-то вроде создания бесконечного списка, как иллюстрирует luqui.
Факторное объяснение TomMD хорошее. Подпись типа Fix - (a -> a) -> a
. Подпись типа для (\recurse d -> if d > 0 then d * (recurse (d-1)) else 1)
- (b -> b) -> b -> b
, другими словами, (b -> b) -> (b -> b)
. Поэтому можно сказать, что a = (b -> b)
. Таким образом, исправление принимает нашу функцию, которая равна a -> a
, или действительно, (b -> b) -> (b -> b)
, и вернет результат типа a
, другими словами, b -> b
, другими словами, еще одна функция!
Подождите, я думал, что он должен был вернуть фиксированную точку ... не функция. Ну, это так, вроде (поскольку функции - это данные). Вы можете себе представить, что это дало нам окончательную функцию для поиска факториала. Мы дали ему функцию, которая не умеет рекурсивно (поэтому один из параметров к ней - это функция, используемая для рекурсии), и fix
научил ее, как рекурсировать.
Помните, как я сказал, что f
должен сгенерировать некоторую структуру, чтобы более поздний f
мог совпадение и завершение шаблона? Ну, это не совсем так, я думаю. TomMD проиллюстрировал, как мы можем расширить x
, чтобы применить функцию и перейти к базовому корпусу. Для его функции он использовал if/then, и именно это вызывает прекращение. После повторных замещений часть в конечном итоге перестает определяться в терминах x
, и именно тогда она является вычислимой и полной.
шалость ответ «исправление не имеет реального использования, это как раз там, так что вы можете набрать' исправить error' в GHCI и чувствовать себя хорошо.» –
@TomMD - Смешно. Я запомню, что если кто-нибудь когда-нибудь спросит меня, что исправить, и я чувствую себя ornery. :-) –
Обычно я пишу 'fix' как' fix f = f (fix f) '. Короткая, простая, работает и идентична математическому определению. – newacct