Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using foldl to count number of true values

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?

like image 998
Daniel O Avatar asked Feb 21 '09 21:02

Daniel O


People also ask

How to count true or false values in Excel?

After this introduction, let's continue with how you can count TRUE or FALSE values in Excel. COUNTIFS and COUNTIF functions are used to count values based on a criteria. Both function share a similar syntax, which involves range and criteria pairs.

How do I Count false values in a Dataframe?

df = pd.DataFrame ( {'A': [True, False, True, False, True]}) print (df ['A'].value_counts ()) # True 3 # False 2 # Name: A, dtype: int64 To calculate True or False values separately, don't compare against True / False explicitly, just sum and take the reverse Boolean via ~ to count False values:

How do I get the total amount of true values in Excel?

Will get you the total amount of True values per column. For row-wise count, set axis=1 . Adding a sum () in the end will get you the total amount in the entire DataFrame. returns a boolean value. True indicates a missing value. returns column wise sum of True values. returns total no of NA elements.

How to calculate true and false values separately from a Boolean?

To calculate True or False values separately, don't compare against True / False explicitly, just sum and take the reverse Boolean via ~ to count False values: This works because bool is a subclass of int, and the behaviour also holds true for Pandas series / NumPy arrays.


2 Answers

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

like image 136
Logan Capaldo Avatar answered Oct 12 '22 23:10

Logan Capaldo


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.

like image 32
Jay Conrod Avatar answered Oct 13 '22 01:10

Jay Conrod