我想在一个表达式中一次附加3个或更多列表。
a ++ b ++ c
将从左到右或从右到左评估++运算符?
1. (a ++ b) ++ c
2. a ++ (b ++ c)
我会说选项2,因为如果++是前缀函数,我们会写++ a ++ b c
,这自然会导致首先评估++ b c
。我不确定我是否正确。
但如果它是选项1,在我看来,从右到左明确地改变评估顺序更有效:
a ++ (b ++ c)
原因如下:a ++ b ++ c
将首先在n个步骤中评估ab ++ c
(其中n是a的长度,ab当然是a和b的连接)然后到{{1在n + m个更多的步骤中(m是b的长度,因此n + m是ab的长度),这使得总共2n + m步。鉴于abc
将首先以m步为单位评估为a ++ (b ++ c)
,然后再向n {+ 1}}进行评估,而不仅仅是n + m步。
我是haskell的新手并不确定我在说什么,我想要一些确认。
答案 0 :(得分:11)
a ++ b ++ c
被解析为
a ++ (b ++ c)
正是您所描述的原因:如果(++)
是左关联的,那么a ++ b ++ c
会复制a
两次。您可以使用
Prelude> :i (++)
将以
回复infixr 5 ++
其中infixr
表示“中缀,右联想”。
答案 1 :(得分:6)
从ghci
开始,执行:i
:
Prelude> :i (++)
(++) :: [a] -> [a] -> [a] -- Defined in GHC.Base
infixr 5 ++
这表明++
是(中缀和)右关联,并将从右到左进行评估。我不知道,但是我愿意打赌,当他/她做出正确联想时,实施该问题的人都会考虑到你的问题。
答案 2 :(得分:3)
还有concat
函数可以连接任意数量的列表:
Prelude> :t concat
concat :: [[a]] -> [a]
Prelude> concat [[1], [2,3], [42,911]]
[1,2,3,42,911]