Haskell 理解和函数的实现

Haskell 理解和函数的实现,haskell,Haskell,我开始使用Haskell,遇到了以下sum函数的实现: sum [] = 0 sum (x:xs) = x + sum xs 然后有一个解释显示了函数在实际示例中的行为: sum [1,2,3] 1 + (sum [2,3]) 1 + (2 + sum [3]) 1 + (2 + (3 + sum [])) 1 + (2 + (3 + 0)) = 6 我不明白,为什么每次调用sum[x]时,列表都会变小1个元素 我唯一的假设是,当构造(x:xs)被执行时,列表的元素x不仅被检索,而且被删除

我开始使用Haskell,遇到了以下
sum
函数的实现:

sum [] = 0
sum (x:xs) = x + sum xs
然后有一个解释显示了函数在实际示例中的行为:

sum [1,2,3]

1 + (sum [2,3])
1 + (2 + sum [3])
1 + (2 + (3 + sum []))
1 + (2 + (3 + 0))
= 6
我不明白,为什么每次调用
sum[x]
时,列表都会变小1个元素


我唯一的假设是,当构造
(x:xs)
被执行时,列表的元素
x
不仅被检索,而且被删除(类似于堆栈
pop()
方法),但我对此不确定。

在符号
x:xs
中,x是列表的头部,它是1项,xs是列表的尾部,它是一个包含0个或更多项的列表

因为递归调用是在xs上进行的,所以问题大小集在每个递归级别上都会减少1。

它是


基本上,您再次调用函数时,列表的其余部分与第一个元素相加。

没有“从列表中删除元素”这样的事情。列表是不可变的,就像任何其他对象一样。现在,关于实施,在:

sum (x:xs) = x + sum xs
您正在将一个列表模式匹配到它的头
x
和列表的其余部分(没有头)
xs
。具体来说,在
sum[1,2,3]
中,您将得到:

sum (1:[2, 3]) = 1 + sum [2, 3]
如果您还记得,
(:)
用于将元素附加到列表中。所以:
1:[2,3]
实际上是
[1,2,3]
,也可以写成:
1:2:3:[]


您应该记住的唯一一件事是
(x:xs)
上的模式匹配意味着:将列表的头放在
x
中,将列表的其余部分放在
xs

中,这非常有意义!我的错误是,我试图将
(x:xs)
xs
列表中的“for each element
x
”关联起来。。。例如,类似于Java中的
foreach