使用foldl计算真值的数量

时间:2009-02-21 21:07:35

标签: haskell functional-programming count

我正在尝试使用foldl找到一种方法来执行以下功能:

count a = length (filter (\i -> i) a)

它只计算布尔值列表中的值的数量。我自己尝试了

count = foldl (\i -> 
            case i of
                True -> (1+)
                False -> (0+)
            ) 0

哪个甚至没有编译。有什么建议吗?

2 个答案:

答案 0 :(得分:9)

那么让我们看看所涉及的功能类型

Prelude> :t (\i -> case i of { True -> (1+) ; False -> (0+) })
(\i -> case i of { True -> (1+) ; False -> (0+) }) :: (Num t) => Bool -> t -> t
Prelude> :t foldl
foldl :: (a -> b -> a) -> a -> [b] -> a

因此,对于您的Bool s列表,b是Bool,但您使用的函数有Bool作为第一个参数,而不是第二个参数。累积值是第一个参数。所以你可以这样做

foldl (\acc p -> case p of { True -> acc + 1 ; False -> acc }) 0

或者,如果您只想修改参数顺序,请使用原始函数flip

Prelude> :t flip
flip :: (a -> b -> c) -> b -> a -> c

foldl (flip (\i -> case i of
                           True -> (1+)
                           False -> (0+)
             )) 0

或者你可以更简洁:foldl (flip ((+) . fromEnum)) 0

答案 1 :(得分:4)

怎么样:

count = foldl (\i v -> if v then i + 1 else i) 0

没有foldl的另一种方法:

count list = sum $ map fromEnum list

感谢Logan指出fromEnum。之前没有听说过那个。