elm
elm

Reputation: 20435

Transform if else to pattern matching in recursive function

For this function that counts the number of elements in a list that hold a predicate,

count :: (a -> Bool) -> [a] -> Int
count _ [] = 0
count p (x:xs) = (if (p x) then 1 else 0) + count p xs

how to convert the if-else expression onto a pattern matching while preserving the summation.

Upvotes: 0

Views: 734

Answers (3)

Shanthakumar
Shanthakumar

Reputation: 768

You can use bool function from Data.Bool module, which does the pattern matching.

bool :: a -> a -> Bool -> a
bool f _ False = f
bool _ t True  = t

So,

count :: (a -> Bool) -> [a] -> Int
count _ [] = 0
count p (x:xs)  = bool 0 1 (p x) + count p xs

Upvotes: 1

zegkljan
zegkljan

Reputation: 8419

You cannot convert if-else to pattern matching at the level of function definition. Pattern matching is for matching a value against its constructors. If-else, on the other hand, tests against True and False.

By pattern matching, you can decide based on how a value looks like, rather than what the value is. To test what the value is, you use either guards or if-else expression.

However, you can convert it to pattern matching using a case-of expression:

count' :: (a -> Bool) -> [a] -> Int
count' _ [] = 0
count p (x:xs) = case (p x) of
                     True  -> 1 + count' p xs
                     False -> count' p xs

This is pattern matching against the constructor of the Bool data type, which has two constructors - True and False, without any actual data.

Upvotes: 3

thor
thor

Reputation: 22570

You can do:

count' :: (a -> Bool) -> [a] -> Int
count' _ [] = 0
count' p (x:xs) | p x = 1 + count' p xs
count' p (x:xs) | otherwise = 0 + count' p xs

Upvotes: 2

Related Questions