Reputation: 597
I am trying to create a function countElems
that takes an Int
and a [Int]
and returns how many of that specific Int
is in the list. So far I have:
countElems :: Int -> [Int] -> Int
countElems n (x:xs)
| xs == [] = 0
| n == x = 1 + countElems n xs
| n /= x = countElems n xs
When run, this seems to work, but on further inspection, if you enter countElems 9 [5, 3, 9, 3, 9]
the output is 1
instead of 2
. I can see this is because it checks that xs == []
before seeing if n == x
resulting in the incorrect output, but if I swap those two cases around is says Non-exhaustive pattern
.
Edit after further thought:
I could eliminate the error @user2407038 posted with this code:
countElems :: Int -> [Int] -> Int
countElems _ [] = 0
countElems n (x:xs)
| n == x = 1 + countElems n xs
| n /= x = countElems n xs
It looks a less elegant but works just the same?
Upvotes: 0
Views: 3993
Reputation: 36329
Another one without any recursive clauses:
countElem e = length . filter (e ==)
Upvotes: 6
Reputation: 1029
You could also write it using map:
countElems :: Int -> [Int] -> Int
countElems n xs = sum $ map (fromEnum . (==n)) xs
Upvotes: 0
Reputation: 14578
Your function is non-exhaustive regardless of which order you place the guards in. Consider countElems 9 []
. This is an error since no pattern matches the empty list. (Maybe this is desired behaviour for your case - but typically errors are bad). Consider using pattern matching here:
countElems n (x:xs) = fromEnum (n == x) + countElems n xs
countElems _ [] = 0
The fromEnum
avoids if
which I like, but you don't have to use it.
There is probably no need to use explicit recursion here. Try \x = length . filter (==x)
.
Upvotes: 2
Reputation: 35983
In your first check (xs == [] = 0
) you forget to check whether x==n
in which case the result should be 1
instead of 0
:
countElems n (x:xs)
| xs == [] = if x==n then 1 else 0
| n == x = 1 + countElems n xs
| n /= x = countElems n xs
Another (probably more straightforward) implementation might look at the list as a whole:
cE n [] = 0
cE n (x:xs) = (if n==x then 1 else 0) + (cE n xs)
Upvotes: 2