bog*_*jov 2 haskell functional-programming list filter
我正在尝试开始学习haskell,并提出了一个问题.说,我有一个功能
countFilter :: (a -> Bool) -> [a] -> ([a], Int)
countFilter a z = case z of [] -> ([], 0);
(x:xs) -> (filter a z , length (filter a z))
Run Code Online (Sandbox Code Playgroud)
它返回一个列表,其中所有项都适用于某个谓词和该列表的长度,这是不相关的.
countFilter (<7) [1,2,4,7,11,8,2]
将输出([1,2,4,2], 4)
.
如何创建这样的输出:([7,11,8], 4)
使用相同的谓词(<7)?
如果我正确理解了您的问题,您希望返回与谓词不匹配的所有元素(< 7)
作为该对的第一个元素.
在这种情况下,您可以简单地使用该not
函数来翻转结果布尔值.
即创建一个新的谓词(\x -> not (oldPred x))
,或使用函数组合(not . oldPred)
::
countFilter :: (a -> Bool) -> [a] -> ([a], Int)
countFilter f xs = (filter (not . f) xs, length (filter f xs))
Run Code Online (Sandbox Code Playgroud)
注意,这两个filter
并length
可以处理空列表,所以你不需要写case
自己.
或者,您可以使用分区功能创建两个列表,这样您就不会过滤两次列表:
import Data.List
countFilter :: (a -> Bool) -> [a] -> ([a], Int)
countFilter f xs = let (ys, zs) = partition (not . f) xs
in (ys, length zs)
Run Code Online (Sandbox Code Playgroud)
可能有可能创建一个更有效的版本而不使用length
,但我把它留作练习:-)