在Haskell中,将函数应用于列表的每个第N个元素的最常用方法是什么?

时间:2014-09-25 13:53:24

标签: list haskell repeat sieve-of-eratosthenes circular-list

我遇到一些元素列表xs非常常见,并希望对每个第N个元素做一些事情。最简单的例子是Sieve或Erastothenes,你想要“敲掉”给定素数的每一个倍数。我可以这样做的两种方法是通过计数器变量传递显式递归;或zipWith ($) (cycle (replicate (n-1) id ++ f))。那么哪种方式更好/更优雅/更常用,或者是否有一些我找不到的像mapEveryN :: (a -> a) -> Int -> [a] -> [a]这样的库函数?

1 个答案:

答案 0 :(得分:2)

正如你和bheklilr所说,cycle提供了一个很好的方法来实现这一目标。你可以稍微利用懒惰:

mapEvery :: Int -> (a -> a) -> [a] -> [a]
mapEvery n f = zipWith ($) (drop 1 . cycle . take n $ f : repeat id)

zipWithcycle的使用似乎更加惯用(复杂的行为由更简单的行为组成),而不是手写的递归函数,它结合了两个任务。

注意tail此处为n = 0定义了此函数,因此最好drop 1

我不知道这是一个图书馆功能。