def thrice(f):
return lambda x: f(f(f(x)))
print(thrice(thrice)(lambda x: x+3)(2))
print((thrice)(thrice)(lambda x: x+3)(2))
两个印刷语句都给出了答案83,但我不明白答案是如何得出的。任何人都可以告诉我两者之间的区别吗?
答案 0 :(得分:3)
两者之间的唯一区别是一对无意义的括号,所以当然它们给出了相同的答案。这与要求这两者之间的差异是一样的:
math.abs(2)
(math.abs)(2)
或者,甚至更好(感谢OlivierMelançon指出这一点),这两者之间存在差异:
1 + 2
(1) + 2
实际上,没有区别。解析它们的第一步有点不同,但它们最终得到相同的AST,因此字节码相同,因此行为相同。
你可能想要问一下:
>>> thrice(thrice(lambda x: x+3))(2)
29
>>> thrice(thrice)(lambda x: x+3)(2)
83
这是一个很大的不同。
在第一个中,我们在lambda上调用thrice
,所以它给我们一个函数,它增加3,然后加3,然后加3,所以它增加9.然后我们调用{{ 1}},所以它给了我们一个函数,它增加9,然后加9,然后加9,所以它增加了27.然后我们在2上调用它,当然得到29。
在第二个问题中,我们在thrice
上调用thrice
,因此它为我们提供了三重函数的功能,无论我们要求它做什么3 ** 3(27)次。然后我们在lambda上调用它,所以它增加了3,37次,这意味着它增加了81.然后我们在2上调用它,得到83.
如果您将thrice
和thrice
应用于thrice(thrice)
而不是lambda x: x+1
,那么可能不那么令人困惑,因此您不会将这些单独的3混淆,如果您将最终函数调用0而不是2。
对于大多数功能,你不能通过编写类似的东西来混淆自己 - 一个版本或另一个版本将是一个简单的lambda x: x+3
。 (尝试撰写TypeError
或math.fabs(math.fabs)
,看看会发生什么。)是什么让int(int)
如此特别?
好吧,想想thrice
的类型。你给它任何类型为thrice
的函数(也就是说,它接受某种类型A->A
的值并返回相同类型A
的值),并返回另一个类型的函数A
。但这意味着它本身就是A->A
类型的函数,所以你可以自己调用它。这是看起来真正令人兴奋的事情之一,直到你想到这些类型,但是一旦你做到这一点,那就没那么令人兴奋了。 "No, John, you are the type theory!" And then John was a Haskell.