在JavaScript中的y组合 [英] y-combinator in javascript
问题描述
const y = f =>我已经在js中构建了一个y-combinator。 {const g = self => x => F(自(个体))(X);返回g(g);}
并且我像这样简化了这段代码
const y = f => {const g = self => F(自(个体)); return g(g);}
这会得到无限递归。
这两个版本有什么区别?
如果您不了解两者的区别,我会惊讶于您实际构建了它们。尽管如此,也许证明两者之间差异的最好方法是遵循他们的评估。
const y = f => {
const g = self => x => f(self(self))(x)
return g(g)
}
y(z)...
//(self => x (self(self))(x))(self => x => z(self(self))(x))...
//返回:
/ / x => z(自己=> x1 => z(self(self))(x1))(self => x2 => z(self(self))(x2)))(x)
好的,所以 y(z)
(其中 z
是一些函数,没关系)返回一个函数 x => ......
。现在,我们将它与第二个定义进行比较。
$ b $ b
const y = f => {
const g = self => f(self(self))
return g(g)
}
y(z)...
//(self => z(self (self(self))(self(self))(self(self))(self(self)) ))...
// z(z((self(自我))> z(self(self)))(self => z(self(self)))))...
(self(self(self)))(self => z(self(self))))))...
// z(z(z (self(self(self)))(self => z(self(self)))))))...
// ...并且on和on
所以 交替Y-组合 这里我们可以从头开始构建一个Y组合器 让我们来测试它 或者我最近的最爱 I have built a y-combinator in js like this and I simplified this code like this this get an infinite recursion.
What's the difference between these two versions? If you don't understand the difference between the two, I would be surprised that you actually built them. Nevertheless, perhaps the best way to demonstrate the difference between the two, is to follow their evaluation Ok, so Now let's compare that to your second definition So Alternate Y-combinators Here we can build a Y-combinator from the ground up Let's test it out
Or my recent favourite
这篇关于在JavaScript中的y组合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! y(z)
永不终止 - 至少在使用应用性命令评估的JavaScript中 - 其中函数参数在被调用函数应用之前被评估
//标准定义
const Y = f => f(Y(f))
//防止立即无限递归顺序语言(JS)
const Y = f => f( x => Y(f)(x))
//使用U combinator删除对自己的引用
const U = f(f)
常数Y = U(h => f => f(x)> h(h)
const U = f =>>
f => f(x => h(h)(f)(x)))// range :: Int - > Int - > [x] = y(f => acc => x => y => x> y?acc:f([... acc,x])(x + 1) )([])// fibonacci :: Int - > Intconst fibonacci = Y(f => a => b => x => x === 0→a:f(b)(a + b)(x-1))(0) console.log(range(0)(10).map(fibonacci))// [0,1,1,2,3,5,8,13,21,34,55]
//简化的Yconst Y = f => x => f(Y(f))(x)// range :: Int - > Int - > [x] = y(f => acc => x => y => x> y?acc:f([... acc,x])(x + 1) )([])// fibonacci :: Int - > Intconst fibonacci = Y(f => a => b => x => x === 0→a:f(b)(a + b)(x-1))(0) console.log(range(0)(10).map(fibonacci))// [0,1,1,2,3,5,8,13,21,34,55]
const y = f => { const g = self => x => f(self(self))(x); return g(g);}
const y = f => { const g = self => f(self(self)); return g(g);}
const y = f => {
const g = self => x => f(self(self))(x)
return g(g)
}
y (z) ...
// (self => x => z(self(self))(x)) (self => x => z(self(self))(x)) ...
// returns:
// x => z((self => x1 => z(self(self))(x1))(self => x2 => z(self(self))(x2)))(x)
y(z)
(where z
is some function, it doesn't matter) returns a function x => ...
. Until we apply that function, evaluation stops there.const y = f => {
const g = self => f(self(self))
return g(g)
}
y (z) ...
// (self => z(self(self))) (self => z(self(self)))
// z((self => z(self(self)))(self => z(self(self)))) ...
// z(z((self => z(self(self)))(self => z(self(self))))) ...
// z(z(z((self => z(self(self)))(self => z(self(self)))))) ...
// z(z(z(z((self => z(self(self)))(self => z(self(self))))))) ...
// ... and on and on
y (z)
never terminates – at least in JavaScript which uses applicative order evaluation – where function arguments are evaluated before the called function is applied
// standard definition
const Y = f => f (Y (f))
// prevent immediate infinite recursion in applicative order language (JS)
const Y = f => f (x => Y (f) (x))
// remove reference to self using U combinator
const U = f => f (f)
const Y = U (h => f => f (x => h (h) (f) (x)))
const U = f => f (f)
const Y = U (h => f => f (x => h (h) (f) (x)))
// range :: Int -> Int -> [Int]
const range = Y (f => acc => x => y =>
x > y ? acc : f ([...acc,x]) (x + 1) (y)) ([])
// fibonacci :: Int -> Int
const fibonacci = Y (f => a => b => x =>
x === 0 ? a : f (b) (a + b) (x - 1)) (0) (1)
console.log(range(0)(10).map(fibonacci))
// [ 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55 ]
// simplified Y
const Y = f => x => f (Y (f)) (x)
// range :: Int -> Int -> [Int]
const range = Y (f => acc => x => y =>
x > y ? acc : f ([...acc,x]) (x + 1) (y)) ([])
// fibonacci :: Int -> Int
const fibonacci = Y (f => a => b => x =>
x === 0 ? a : f (b) (a + b) (x - 1)) (0) (1)
console.log(range(0)(10).map(fibonacci))
// [ 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55 ]