α- и η-конверсии

В предыдущей главе мы осознали важную проблему, возникающую при подстановке. Тут поговорим подробнее о методе решения этой проблемы.

α-конверсия

Имя связанной переменной — не более чем метка: λx.x\lambda x.\,x и λy.y\lambda y.\,y — одна и та же функция.

λx.M  =α  λy.M[x:=y],yFV(M)\lambda x.\,M \;=_\alpha\; \lambda y.\,M[x{:=}y], \qquad y \notin \mathrm{FV}(M)
(1.6)

Особо одарённые товарищи от возни с переименованием избавляются и используют индексы де Брёйна: сами лямбды остаются, но становятся безымянными, а каждое вхождение переменной записывается числом — сколько лямбд нужно пройти от него вверх до связывателя (отсчёт с нуля, 00 — ближайшая охватывающая лямбда). Тогда α-эквивалентные термы получают одинаковую запись, и α-конверсия как понятие исчезает.

  • λx.x\lambda x.\,xλ.0\lambda.\,0 (единственная переменная указывает на свою лямбду);
  • λx.λy.xy\lambda x.\,\lambda y.\,x\,yλ.λ.10\lambda.\,\lambda.\,1\,0 (xx стало 11, а yy00).

η-конверсия

На самом деле это совсем мелочь, но всё равно надо коротко сказать. η-конверсия говорит, что «обёртка» λx.Mx\lambda x.\,M\,x ничем не отличается от самого MM.

λx.(Mx)  =η  M,xFV(M)\lambda x.\,(M\,x) \;=_\eta\; M, \qquad x \notin \mathrm{FV}(M)
(1.7)

η-редукция сворачивает такую обёртку влево, а η-экспансия разворачивает её вправо.

В Haskell это знакомый point-free стиль:

sum xs = foldr (+) 0 xs
-- превращается в
sum = foldr (+) 0