Haskell:记住列表中的前一个元素

时间:2017-08-12 23:58:40

标签: haskell scope

简单的问题,不确定如何做。

我正在从Data.List编写一个更有限的sum函数版本,并且具有以下代码:

-- Sum the contents of a list

sum' :: Num a => [a] -> a

sum' [] = 0

sum' (x:xs) = x + sum' rest where
              rest = drop (succ (elemIndex x xs)) xs 

我相信如果elemIndex的 x 参数在当前列表元素的范围内,这将有效。

我想在不使用Foldable的情况下做到这一点,尽可能基本,因为Graham Hutton的 Haskell编程中的问题是在他涵盖可折叠或大多数Haskell想法之前编写的。 / p>

2 个答案:

答案 0 :(得分:3)

如果你想“手动”写一个求和函数,它只是第一个元素加上剩余元素的总和:

sum' :: Num a => [a] -> a

-- The sum of an empty list is 0
-- The "base case" of the recursion
sum' [] = 0

-- The sum of a non-empty list is equal to the first element
-- plus the sum of the rest of the list 
sum' (x:xs) = x + (sum' xs)

哪个好,但过了一会儿,你会发现你会做很多这样的确切模式:在保持累加器的同时循环遍历列表。在这种情况下,数字的总和是累加器。

这就是fold的用武之地。折叠如何工作的完整描述是不可能的,但是要使用折叠来汇总数字列表,您可以简单地写一下:

sum' :: Num a => [a] -> a
sum' xs = foldl (+) 0 xs

折叠基本上在列表中的每个元素之间插入你给它的函数,所以

foldl (+) 0 [1, 2, 3, 4, 5]

基本上是一样的(注意左边的0。这是起始总和):

0 + 1 + 2 + 3 + 4 + 5

关于折叠的更多信息,我写了一个答案(以及许多其他人)here。值得一看。

答案 1 :(得分:0)

如果你理解currying,你可以更简单地说:

sum' = foldl (+) 0