[英]Why is a built-in function applied to too few arguments considered to be in weak head normal form?
Haskell 定义说:
表达式是弱头正常形式(WHNF),如果它是:
- 一个构造函数(最终应用于参数),如True,Just(square 42)或(:) 1
- 一个内置函数应用于太少的参数(可能没有),如(+)2或sqrt。
- 或lambda抽象\\ x - >表达式。
为什么内置功能会得到特殊处理? 根据lambda演算, 部分应用函数和任何其他函数之间没有区别,因为最后我们只有一个参数函数。
应用于参数的常规函数,如下所示:
(\x y -> x + 1 : y) 1
可以减少,给予:
\y -> 1 + 1 : y
在第一个表达式中,“最外层”的东西是一个应用程序,所以它不在WHNF中。 在第二个中,最外层的东西是lambda抽象,所以它在WHNF中(即使我们可以在函数体内做更多的缩减)。
现在让我们考虑一下内置(原始)函数的应用:
(+) 1
因为这是一个内置函数,所以我们没有函数体可以用1
代替第一个参数。 评估者“只知道”如何评估(+)
完全“饱和”应用,如(+) 1 2
。 但部分应用的内置功能无法实现; 我们所能做的是产生描述“应用(+)为1,等待一个多参数”的数据结构,而这正是我们试图减少就是 。 所以我们什么都不做。
内置函数是特殊的,因为它们不是由lambda演算表达式定义的,因此缩减过程不能“看到”它们的定义。 因此,与普通函数应用程序不同,内置函数应用程序必须通过累积参数来“减少”,直到它们完全“饱和”(在这种情况下,通过运行内置的任何神奇实现来减少WHNF) 。 不饱和的内置应用程序无法进一步减少,因此已经在WHNF中。
考虑
前奏>让fn = [(+ x)| x < - [1 ..]] !! ñ
前奏>让g = f 20000000 :: Int - > Int
g
此时不在WHNF! 您可以通过评估g 3
来看到这一点,因为在应用参数之前需要WHNF,因此需要显着滞后。 这是在搜索正确的内置函数时遍历列表的时候。 但之后,这个选择被修复了, g
是WHNF(事实上NF:对于lambdas也是如此,也许你对你的问题意味着什么),因此任何后续调用都会立即给出结果。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.