Using foldl to count the number of true values

I am trying to find a way to execute the following function with foldl:

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

It simply counts the number of values ​​that are true in the list of gates. I tried using

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

which didn't even compile. Any suggestions?

+5
source share
2 answers

So let's look at the types of 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 Bools, b is Bool, but the function you use has Boolas 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

, , 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

+9

:

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

foldl:

count list = sum $ map fromEnum list

fromEnum. .

+4

All Articles