Ещё один Y Combinator

Очень красивый и элегантный подход к понятию Y-комбинатора я нашёл у Dan Piponi. Он начинает ну очень издалека.

Допустим, мы хотим прибавить 1 к числам от 0 до 9. Определим функцию, увеличивающую аргумент на 1, и вызовем её через map:

def inc(n):
return n+1
map(inc,range(0,10))

Упростим эту запись с помощью лямбда-функции:

map(lambda x:x+1,range(0,10))

Но что, если вычисления более сложные, и в них задействованы локальные переменные? Например,

def f1(n):
m = 2*n+1
return m+m*m
map(f1,range(0,10))

Переменная m напрашивается своей выделенной функцией:

def f2(n):
def g(m):
return m+m*m
return g(2*n+1)

И снова, как и ранее, можно выразить её через лямбда-запись:

def f3(n):
return (lambda m:m+m*m)(2*n+1)
map(f3,range(0,10))

Ну и финальный вариант в одну строчку:

map(lambda n: (lambda m:m+m*m)(2*n+1),range(0,10))

Но если внутри нашей функции много мелких функций, которые надо скомбинировать?

def f(n):
def g(n):
return 2*n+1

def h(n):
return 3*n-2

return g(h(g(h(n))))

map(f,range(0,10)) 

Переписать их в одну строчку можно так:

map(lambda n: (lambda g,h,n:g(h(g(h(n)))))(lambda n:2*n+1,lambda n:3*n-2,n), range(0,10))

Часть

lambda n: (lambda g,h,n:g(h(g(h(n)))))

описывает кусочек

def f(n):
return g(h(g(h(n))))

который далее получает функции g и h как параметры.

вторая часть

Поделиться статьей ...Share on Facebook0Share on Google+0Tweet about this on TwitterShare on LinkedIn0Share on VKPrint this page

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *