Я читаю книгу «Haskell из первых принципов». На странице 12 мы учимся сокращать лямбда-выражения.
Я не понимаю, почему символ периода между λz и (λm.λn.m) исчез на шаге 3. Когда я заменил x на (λm.λn.m) на шаге 3, я подумал, что нужно заменить только x и не период перед ним. Так что я ожидал (λy.λz. (λm.λn.m) z (yz)) (λp.p) вместо (λy.λz (λm.λn.m) z (yz)) (λp.p)
Вот мой анализ
(λxyz.xz (yz)) (λm.λn.m) (λp.p)
Сделайте каррирование явным.
(λx.λy.λz.xz (yz)) (λm.λn.m) (λp.p)
Подставляем x = (λm.λn.m)
(λy.λz. (λm.λn.m) z (yz)) (λp.p)
Подставляем y = (λp.p)
(λz. (λm.λn.m) z ((λp.p) z))
Заметим, что λz не имеет аргументов. Остается уменьшить (λm.λn.m) z ((λp.p) z)
(λm.λn.m) z ((λp.p) z)
Подставляем m = z
(λn.z) ((λp.p) z)
Здесь есть λn.z (что-то). Но λn.z чего угодно - это просто z. (Поскольку тело λn.z - это просто z, не содержащее n)
z
Вспоминая λz из шага 4, мы получаем
λz.z
Таким образом, мы получаем тот же ответ, что и книга.
Лямбда-нотация с точками действительно неудобна и подвержена такого рода опечаткам. Я не понимаю, почему люди не пишут (λx⟼λy⟼λz⟼xz (yz)) (λm⟼λn⟼m) (λp⟼p) или просто не используют нотацию Haskell (\ x -> \ y-> \ z-> xz (yz)) (\ m -> \ n-> m) (\ p-> p).
Насколько я понимаю, Алонзо Черч написал λx (something) вместо λx.something. Преимущество использования обозначений Чёрча состоит в том, что вы видите, где тело начинается и где заканчивается.
@BobUeland Обычное соглашение заключается в том, что область действия расширяется вправо насколько это возможно. Итак, λx связывает x до первых закрытых скобок или до конца члена. ИМО, приятно иметь возможность писать, например. λxyz.xz (yz) без дополнительных скобок. Почему-то я предпочитаю точку более шумному ->
. Черч ввел термины, используя обозначения λx[M]
и {F}[M]
, но затем сразу же написал: «Формула λx1[λx2[...λxn[M]...]]
может быть сокращена как λx1x2...xn.M
или как λx1x2...xnM
» [Church36]. Последнее немного неоднозначно. В то время он не сокращал a(b)
как ab
.
Это определенно, определенно, определенно опечатка.
Если это опечатка, то к чему сводится выражение. Ответ в книге - λz.z. Это правильно?
@BobUeland быстро тестирует его на GHCi, кажется, да. let f = (\x y z -> x z (y z))(\m n -> m)(\p -> p)
, :info f
=> f :: t -> t
. (Это только информация о типе, но, учитывая задействованные выражения, я бы подумал, что это может быть только \x -> x
).
У меня нет экземпляра этой книги, но не опечатка? (Если период загадочным образом появится снова на следующем шаге, то это будет наиболее вероятно.)