使用foldl时如何在列表中获取元素的索引

时间:2019-05-11 15:01:13

标签: haskell

我必须编写一个函数,以使用The number of people who get 10 : (input)从列表(sum k=1 to n) (-1)^(k+1) * a_k计算[a_1,a_2,a_3,..a_n]

foldl

我设法编写了这段代码,但是我不知道如何替换calculate list = foldl (\x xs -> x + (xs * (-1)^(??? + 1)) ) 0 list ,如何获取给定列表中元素的索引。

2 个答案:

答案 0 :(得分:6)

我们可以用更简单的方法来实现。我们可以考虑一个无限列表,其中重复两个函数:id :: a -> anegate :: Num a => a -> a,并使用cycle :: [a] -> [a]构造一个无限列表。因此,cycle [id, negate]将产生一个类似于[id, negate, id, negate, ...]的列表。

然后我们可以使用zipWith用值列表来压缩无限列表,并使用($) :: (a -> b) -> a -> b作为“ zip函数”,这样我们得到:

Prelude> zipWith ($) (cycle [id, negate]) [1,4,2,5]
[1,-4,2,-5]

最后,我们可以使用sum :: Num a => [a] -> a来汇总这些值。

因此我们可以将函数定义为:

calculate :: Num a => [a] -> a
calculate = sum . zipWith ($) (cycle [id, negate])

例如:

Prelude> calculate [1,4,2,5]
-6

答案 1 :(得分:3)

由于威廉(Willem)的评论,我设法做到了:

calculate list = foldl (\x (index,el) -> 
    x + (el * (-1)^(1 + index))
    ) 0 (zip [1..length(list)] list)

对我来说,它更具可读性,因为我是新手,我只是为其他人发布了它:)