[英]What does the 'outermost part' of expression mean in Haskell
这是真正的初学者,我正在阅读NF和WHNF之间的差异,以及我遇到的各种定义之一
要确定表达式是否处于弱头正常形式,我们只需要查看表达式的最外部分。
我不确定应用什么标准来确定“最外层”部分是什么。 例如(来自@hammer的堆栈溢出回答):
'h' : ("e" ++ "llo") -- the outermost part is the data constructor (:)
(1 + 1, 2 + 2) -- the outermost part is the data constructor (,)
\x -> 2 + 2 -- the outermost part is a lambda abstraction
特别是在那里的第一个例子中,(:)运算符位于'h'和另一个表达式的中间,那么它是如何最外面的部分?
一般来说,在查看表达式时,如何确定最外层部分是什么?
好问题。 这里,“最外面的”(或“最上面的”)描述了一种参考表达式的标准抽象视图的位置,该视图可以与其实际语法不同。 例如,这两个表达式:
(1, 2)
(,) 1 2
在Haskell中具有相同的含义。 事实证明,在这两种情况下,构造函数(,)
都是表达式的最外层部分,即使表达式具有不同的语法形式,并且语法中出现在不同物理位置的逗号。
一般来说,Haskell的“标准语法”涉及表单的函数应用:
fexpr expr1 .. exprn
但是,该语言还允许其他类型的语法:
1 + 2 -- infix operators
(3, 4) -- tuples
[5,6,7,8] -- lists
"abc" -- strings
这些替代语法可以转换为标准语法,如下所示:
1 + 2 ==> (+) 1 2
(3, 4) ==> (,) 3 4
[5,6,7,8] ==> (:) 5 ((:) 6 ((:) 7 ((:) 8 [])))
"abc" ==> (:) 'a' ((:) 'b' ((:) 'c' []))
虽然它远非显而易见,但(+)
是一个变量,其值是一个函数(如sqrt
); while (,)
和(:)
是构造函数(就像True
或Just
)。 即使[1,2,3]
是特殊语法,空列表[]
也是一个(一元)构造函数,更令人困惑,而且显而易见! 这就是我在标准语法版本中仍然在右侧使用空列表的原因。
无论如何,一旦转换为标准语法,表达式将是构造函数应用程序,如下所示:
True -- a nullary constructor
(,) (1+2) (2+3) -- constructor expecting two args and fully applied
(:) 5 -- constructor partially applied and expecting one more arg
我们说表达式的“最外层部分”是这个构造函数应用程序,或者它是一个未应用的lambda抽象:
(\x y -> (+) x (length y))
我们说表达式的“最外层部分”是这个未应用的lambda抽象,或者它将是其他东西:
w -- a variable
(\x -> x) 10 -- an applied lambda abstraction
(f x) y ((*) 2 z) -- some other function application
(+) 10 (length (1:[])) -- another function application
我们说表达式的“最外层部分”是变量引用或函数应用程序或其他。
无论如何,如果最外面的部分是构造函数应用程序或未应用的lambda抽象,那么它被称为弱头正常形式。 如果它是别的东西,那就不是。
因此, Just (5+6)
在WHNF中,因为最外面的部分是构造函数Just
的应用程序。 另一方面, sqrt (5+6)
不在 WHNF中,因为最外面的部分是变量sqrt
的应用,而变量不是构造函数。
类似地, 5+6
本身不处于WHNF因为最外部分是可变的应用(+)
至5
和6
,而[5,6]
是在WHNF因为最外部分是(隐含的)构造方法应用(:)
到5
和[6]
。
您必须查看抽象语法树以了解这意味着什么。
:
/ \
'h' ++
/ \
"e" "llo"
(,)
/ \
+ +
/ \ / \
1 1 2 2
\x ->
|
+
/ \
2 2
“Outermost”表示树的根。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.