Как получить нормализованную форму лямбда-выражения?

#python #lambda #inspect

#python #лямбда #Осмотр

Вопрос:

Для какой-то цели мне нужна церковная кодировка чисел, поэтому я определяю числа следующим образом:

 # Let's define zero
zero = lambda f: lambda x: x

# A successor function
successor = lambda n: lambda f: lambda x: f(n(f)(x))

# Now I can define any number inductively/recursively
one = successor(zero)
two = successor(successor(zero))

  

Теперь, если я попытаюсь напечатать источник one , two , и т.д., Полные выражения не будут приведены к их обычным формам:

 import inspect;
print(inspect.getsource(zero))
print(inspect.getsource(one))
print(inspect.getsource(two))
  

Вывод:

 zero = lambda f: lambda x: x
succ = lambda n: lambda f: lambda x:  n(f)(x)
succ = lambda n: lambda f: lambda x:  n(f)(x)
  

Как я могу увидеть уменьшенную форму, где тело самого внутреннего лямбда-выражения для one и two сводится к нормализованной форме (вычисляется?), Т.Е. Я могу определить разницу между сокращенными выражениями one и two .

В качестве ссылки эквивалентная форма one и two может быть следующей:

 zero = lambda f: lambda x: x
one = lambda f: lambda x: f(x)
two = lambda f: lambda x: f(f(x))
  

Но я не могу получить такое же различие от inspect.getsource . Конечно, мне не нужна дословная эквивалентность, но что-то, что все еще способно показывать разные уровни вложенности в one и two .

Комментарии:

1. В Python нет отложенной оценки . Вы можете воспроизвести отложенную оценку с помощью итераторов / генераторов. Но Python с нетерпением оценивается. В любом случае, inspect.getsource это ничего вам не даст, оно опирается на фактический исходный код.

Ответ №1:

Для этого конкретного случая вы можете передать новую лямбда-функцию в качестве аргумента one or two , которая возвращает строку с правильным уровнем стекирования. Однако это не дает вам форму лямбда-входов ( lambda f: lambda x: ).

 zero(lambda x: f'f({x})')('x')
# returns:
'x'

one(lambda x: f'f({x})')('x')
# returns:
'f(x)'

two(lambda x: f'f({x})')('x')
# returns:
'f(f(x))'