使用JavaScript。让我们定义以下内容:
M = f => f(f) // Mocking Bird
I = a => a // Identity
假设现在我们写这个表达式
M( f => M( x => f) )
这似乎是递归的并且达到了最大的callstack。让我们展开一次
( f => M( x => f) ) (f => M( x => f) )
我们看到我们可以继续前进
(f => (x => f)( x => f))(f => (x => f)( x => f))
(x => (f => (x => f)( x => f)))(x => (f => (x => f)( x => f)))
......等等。但是在浏览器或节点中,这不是递归的。它的行为类似于Identity
I('foobar')
// returns 'foobar'
M( f => M( x => f) )('foobar')
// returns 'foobar'
(x => (f => (x => f)( x => f)))(x => (f => (x => f)( x => f))) ('foobar')
// returns 'foobar'
请解释为什么函数在达到最大调用堆栈之前不会自行调用,而是返回一个行为类似于Identity
的函数
使用Python
可以表达同样的现象M = lambda f: f(f)
I = lambda a: a
M( lambda f: M(lambda x: f)) ('foobar')
# returns 'foobar'
I('foobar')
# returns 'foobar'
从
开始M( f => M( x => f) )
如果我们写出内部M( x => f)
M( f => ( x=> f )(x => f) )
我们发现传递给(x => f)(x => f)
的内容并不重要,x
会被忽略,只返回f
M( f => f )
这只是
f => f
答案 0 :(得分:1)
M(/*a*/ f => M( /*b*/ x => f) )('foobar')
使用 f = a :调用a
M(/*b*/ x => *a*)
调用b ,x为b,返回:
/*a*/ f => M(/*b*/ x => f)
用“foobar”调用,所以f是“foobar”:
M(/*b*/ x => "foobar")
“foobar”被退回
基本上它起作用是因为:
M( x => f)
始终返回 f ,因此整个事情等于
M( f => f )
然后呢:
(f => f)(f => f)
是
f => f