Это все чисто функциональный код (кроме самого print
), поэтому мы можем просто использовать подстановку, чтобы визуализировать происходящее:
print(g(2)(f)(lambda x:x+1))
# ^^^^
Шаг 1: Вызов g
с 2
, привязка аргумента g
y
к 2
...
def g(y): # y = 2
return lambda x: x(y)
... дает lambda x: x(2)
.
print((lambda x: x(2))(f)(lambda x:x+1))
# ^^^^^^^^^^^^^^^^^^^
Шаг 2. Вызовите функцию lambda
(которая была возвращена из g
) с помощью f
...
(lambda x: x(2)) # x = f
# ^^^^
... который в свою очередь вызывает f
с 2
...
def f(x): # x = 2
return lambda y: (x, y(x))
... давая lambda y: (2, y(2))
:
print((lambda y: (2, y(2)))(lambda x:x+1))
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Шаг 3. Вызовите функцию lambda
(которая была возвращена из f
через другой lambda
) с помощью lambda x:x+1
...
(lambda y: (2, y(2)) # y = lambda x:x+1
# ^^^^
... давая (2, (lambda x:x+1)(2))
, что в свою очередь вызывает функцию lambda
аргумента с 2
...
lambda x:x+1 # x = 2
... давая 3
, который затем включается в результат внешнего lambda
, давая (2, 3)
:
print((2, 3))
#^^^^^^^^^^^^
Это, наконец, точка, в которой вызывается print
, передавая кортеж в качестве аргумента.