【问题标题】:Filtering a list in Haskell在 Haskell 中过滤列表
【发布时间】:2010-10-20 22:09:31
【问题描述】:

我正在尝试开始学习haskell,但出现了一个问题。 说,我有一个函数

countFilter :: (a -> Bool) -> [a] -> ([a], Int)
countFilter a z = case z of []        -> ([], 0);
                            (x:xs)    -> (filter a z , length (filter a z))

它返回一个列表,其中的所有项目都适用于某个谓词和该列表的长度,这是不相关的。

countFilter (<7) [1,2,4,7,11,8,2] 将输出([1,2,4,2], 4)

如何创建这样的输出:([7,11,8], 4) 使用相同的谓词(

【问题讨论】:

    标签: list haskell functional-programming filter


    【解决方案1】:

    如果我正确理解您的问题,您希望返回所有 与谓词 (< 7) 匹配的元素作为该对的第一个元素。

    在这种情况下,您可以简单地使用not 函数来翻转生成的布尔值。
    IE。创建一个新的谓词(\x -> not (oldPred x)),或者使用函数组合:(not . oldPred)

    countFilter :: (a -> Bool) -> [a] -> ([a], Int)
    countFilter f xs = (filter (not . f) xs, length (filter f xs))
    

    注意filterlength都可以处理空列表,所以你不需要自己写case


    或者,您可以使用partition 函数创建两个列表,这样您就不会两次过滤列表:

    import Data.List
    
    countFilter :: (a -> Bool) -> [a] -> ([a], Int)
    countFilter f xs = let (ys, zs) = partition (not . f) xs
                       in (ys, length zs)
    

    也许可以创建一个不使用 length 的更高效的版本,但我将其留作练习 :-)

    【讨论】:

    • 太棒了!我只是没有注意到参考文献中的“不”:)试图实现“否定”......我还没有进入分区和导入思想,但我会回复你的答案,因为我'将继续我的 Haskell 路径。)
    猜你喜欢
    • 2014-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多