在haskell [1,2,3,4,5] ++ [6]给出[1,2,3,4,5,6]但[6] ++ [1,2,3,4, [5]给出了[6,1,2,3,4,5]。因此,如果我在列表的开头或末尾附加,那就很重要了。
但现在让我们在递归函数f1和f2中尝试相同的事情
f1 x accumulator | x == 0 = accumulator
| otherwise = f1 (x-1) accumulator++[x]
现在下面的f2是相同的函数,除了我将元素附加在列表的开头。
f2 x accumulator | x == 0 = accumulator
| otherwise = f2 (x-1) [x]++accumulator
奇怪的是,两个函数对同一输入返回相同的顺序。为什么呢?
例如:
[1,2,3,4,5]++[6]
返回[1,2,3,4,5,6]
[6]++[1,2,3,4,5]
返回[6,1,2,3,4,5]
f1 6 []
返回[1,2,3,4,5,6]
f2 6 []
也会返回[1,2,3,4,5,6]。
答案 0 :(得分:0)
有趣的问题。您被误导是因为您在以下表达式中将++
运算符的优先级归于(错误地):
f1 (x-1) accumulator++[x]
表示(f1 (x-1) accumulator)++[x]
和不 f1 (x-1) (accumulator++[x])
。
同样,f2 (x-1) [x]++accumulator
表示(f2 (x-1) [x]) ++ accumulator
而不 f2 (x-1) ([x]++accumulator)
。
因此:
f1 6 []
= (f1 5 [])++[6]
= ((f1 4 [])++[5])++[6]
...
= (...((f1 0 []) ++ [1]) ++ ...) ++ [6]
= [1,2,3,4,5,6]
和
f2 6 []
= (f2 5 [6])++[]
= ((f2 4 [5])++[6])++[]
...
= ((...((f2 0 [1])++[2])++ ...) ++ [6]) ++ []
= [1,2,3,4,5,6]
关于运算符与函数应用程序的优先级,请参阅this question。