标签:版本 执行 函数返回 相等 函数调用 code 提取 == 取出
// Y组合子
fact = n => n == 1 ? 1 : n * fact(n - 1)
// 无法匿名调用
(n => n == 1 ? 1 : n * fact(n - 1))(5)
// 参数可以命名, 消灭掉里面掉fact
fact = (f, n) => n == 1 ? 1 : n * f(f, n - 1);
// 只能有一个参数
fact = f => n => n == 1 ? 1 : n * f(f)(n - 1);
// 将fact带入 amazing!!! ??????
(f => n => n == 1 ? 1 : n * f(f)(n - 1))(f => n => n == 1 ? 1 : n * f(f)(n - 1))(5);
// f(f):2 ---- ---- ^^^
// fact(fact):1
// 开始抽象
fact = f => n => n == 1 ? 1 : n * f(f)(n - 1);
// 先让匿名函数调用自己,把自己传进去,缓存自己,然后将执行函数返回
w = f => f(f)
// 将fact进行自我缓存,将执行函数暴露出来
w(fact)(5)
// 去掉变量的版本
w(f => n => n == 1 ? 1 : n * f(f)(n-1)) (5) // longer version
// f(f) 将他从内部系统中解耦出来
f => n => n == 1 ? 1 : n * f(f)(n - 1);
// 令g = f(f), 把f(f)的自调用,抽离出业务逻辑,以参数的形式传入
f => (g => n => n == 1 ? 1 : n * g(n - 1))( f(f) )
// eta规约 两个lamda算子若对于相同的输入产生相同的输出,则认为它们外延相等,可以互相规约
// eta规约 lamda x.f x === f
// js eta规约 x => f(x) === f(x)
// 实战 f(f)() === v => f(f)(v)
f => (g => n => n == 1 ? 1 : n * g(n - 1))( v => ( f(f)(v) ) )
// 将阶乘函数提取出来(g => n => n == 1 ? 1 : n * g(n - 1)),将之命名为fact0
( fact0 => f => fact0( v => ( f(f)(v) ) )( g => n => n == 1 ? 1 : n * g(n - 1) )
// 将之前的w代入
w(
( fact0 => f => fact0( v => ( f(f)(v) ) )( g => n => n == 1 ? 1 : n * g(n - 1) )
)(5)
// 把fact0解耦出来
( h => w(s => f => s( v => ( f(f)(v) )))(h))( g => n => n == 1 ? 1 : n * g(n - 1))
// Y组合子
( h => w(s => f => s( v => ( f(f)(v) )))(h) )
// 化简
( h => w(f => h( v => ( f(f)(v) ))) )
// 去掉w,最终Y组合子
(h =>
(f => h ( v => f(f)(v) ))
(f => h ( v => f(f)(v) ))
)
标签:版本 执行 函数返回 相等 函数调用 code 提取 == 取出
原文地址:https://www.cnblogs.com/pluslius/p/12384805.html