I'm trying to find a way to do the following function with 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. 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
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
How about:
count = foldl (\i v -> if v then i + 1 else i) 0
Another way to do it without foldl
:
count list = sum $ map fromEnum list
Credit to Logan for pointing out fromEnum
. Hadn't heard of that one before.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.