为什么在开始或结束时附加在这个功能中并不重要?哈斯克尔

时间:2018-06-04 21:07:46

标签: list recursion append

在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]。

1 个答案:

答案 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