简体   繁体   English

使用foldl计算真值的数量

[英]Using foldl to count number of true values

I'm trying to find a way to do the following function with foldl: 我正在尝试使用foldl找到一种方法来执行以下功能:

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

It just counts the number of values that are true in a list of booleans. 它只计算布尔值列表中的值的数量。 I did try it myself with 我亲自尝试过

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

Which did not even compile. 哪个甚至没有编译。 Any suggestions? 有什么建议?

So let's check out the types of the functions involved 那么让我们看看所涉及的功能类型

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

So for your list of Bool s, b is Bool, but the function you're using has Bool as the first argument, not the second. 所以对于你的Bool列表,b是Bool,但你使用的函数将Bool作为第一个参数,而不是第二个参数。 The accumulated value is the first argument. 累积值是第一个参数。 So instead you could do 相反,你可以这样做

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

Or if you'd just like to fix the argument order, use your original function with flip 或者,如果您只想修改参数顺序,请使用原始函数进行flip

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

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

Or you can be more succinct: foldl (flip ((+) . fromEnum)) 0 或者你可以更简洁: foldl (flip ((+) . fromEnum)) 0

How about: 怎么样:

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

Another way to do it without foldl : 另一种没有foldl

count list = sum $ map fromEnum list

Credit to Logan for pointing out fromEnum . fromEnum Logan指出来自fromEnum Hadn't heard of that one before. 以前没有听说过那个。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM