在Haskell中,为什么将x ++ y : zas解析为x ++ (y : z)not (x ++ y) : z?
例如,[1] ++ 2 : [3]计算为[1,2,3]。
两者(++)和(:)都具有优先级5的右关联。
Wil*_*sem 11
它们是正确关联的事实意味着可以将它们解析为“从右到左”。因此,这意味着x y y z被解析为x y (z y)。因此,这x ++ y : z的确被解析为x ++ (y : z)。
有充分的理由使两者(:)和(++)权利相关联。对于“ cons” (:)运算符,这意味着我们可以编写1 : 4 : 2 : [],因为它被解析为1 : (4 : (2: [])),这在类型方面是正确的。如果将其解析为like ((1:4):2:[]),则将1:4是错误的,因为它期望将一个项目作为第一个操作数,并将这些项目的列表作为第二个操作数。当然,我们仍然可以让Haskell解析器将其解析为一个列表,但这会导致大量的括号。
对于(++)这是更好地分析它从右到左,以及由于性能原因。x ++ y的线性时间为x。因此,这意味着如果我们解析x ++ (y ++ z),它将需要| x |。+ | y | 脚步。如果将其解析为(x ++ y) ++ z,则需要2×| x | + | y | ,自从我们第一次申请以来,(x ++ y)它的大小为x,但之后(x ++ y) ++ z的大小为x ++ y。因此,这意味着如果我们将n个大小为m的列表连接起来,它将不会以O(n×m)的形式运行,而是以O(n 2 ×m)的形式运行。