haskell,筛选带有多个过滤器的列表

时间:2014-04-26 14:31:57

标签: list haskell filter

给出类型

sieve :: [a -> Bool] -> [a] -> [[a]]

我必须编写一个函数,它使用函数列表[a->Bool]过滤列表。 每个过滤器必须只筛选剩余的过滤器。 它返回一个列表列表,每个列表代表筛子捕获的内容。 最后一个列表是任何过滤器都没有捕获到的。 e.g。

sieve [(<3),(>7),odd] [1..10] gives back [[1,2],[8,9,10],[3,5,7],[4,6]]

我知道筛子必须以这种方式开始...

sieve fs xs = concat $ filter () ...

我的问题是: 在我可以进入复杂的工作部分,逐步过滤之前,我不知道如何访问函数列表中的每个函数并在[a]列表中使用它。 如果它是一个函数,那么使用(filter f xs)

会很容易

我尝试了很多而且没有得到它。

有人可以帮助,并可能提供一些提示如何管理一个接一个的过滤系统? 任何提示都是受欢迎的。

编辑:

我现在有这个: 这是我认为它应该工作的方式,但我有一个问题否定布尔函数... 你能帮忙吗?

    sieve :: [a -> Bool] -> [a] -> [[a]]
    sieve [] xs = [xs]
    sieve (f:fs) xs = (filter f xs) : (sieve fs (filter nf xs))

            where nf = not f

这不起作用,因为我可能不会像这样使用(不是f)。 有什么想法吗?

编辑:最终解决方案

partition p xs =(filter p xs,filter(not。p)xs)

    sieve :: [a -> Bool] -> [a] -> [[a]]
    sieve [] xs = [xs];
    sieve (f:fs) xs = p1 : (sieve fs p2)
    where p1 = fst (partition f xs)
          p2 = snd (partition f xs)

1 个答案:

答案 0 :(得分:1)

您希望为列表的每个元素执行某些操作并在执行此操作时累积结果,这正是折叠函数的用途:

import Data.List (partition, foldl')

sieve fs xs = let (p1, p2) = fold fs xs in p2 ++ [p1]
    where fold fs xs = foldl' step (xs, []) fs
          step (lst, rs) f = let (r1, r2) = partition f lst in (r2, rs++[r1])

要使用递归来实现它,您需要做的是过滤前面的过滤器留下的列表,并在执行此操作时收集结果:

import Data.List (partition)

sieve [] xs = [xs]
sieve (f:fs) xs = let (p1, p2) = partition f xs
                   in p1 : sieve fs p2