Reputation: 11307
Given a list of lists, I'd like to find the maximum number of times a particular element occurs in one of the sub-lists.
So given [[1,4],[4,3],[1,4,4,3]]
I expect output to be 2
because the number 4
occurs twice in one of the sub-lists (and no more than twice).
My approach was to eliminate all the numbers which are not 4
from the sublists, and then get the maximum length of all the sub-lists. The first step was OK:
map (filter (==4)) [[1,4],[4,3],[1,4,4,3]]
But adding length
gives me an error:
map (length $ filter (==4)) [[1,4],[4,3],[1,4,4,3]]
Couldn't match expected type ‘[Integer] -> b’ with actual type ‘Int’ Relevant bindings include it :: [b] (bound at <interactive>:11:1) In the first argument of ‘map’, namely ‘(length $ filter (== 4))’ In the expression: map (length $ filter (== 4)) [[1, 4], [4, 3], [1, 4, 4, ....]] In an equation for ‘it’: it = map (length $ filter (== 4)) [[1, 4], [4, 3], [1, 4, ....]]
Why doesn't this work? - Haskell noob if you did't notice :)
Upvotes: 0
Views: 87
Reputation: 23135
You just need to compose length
and filter (==4)
with .
, not $
, because both length
and filter (==4)
are functions, not a function and a value, which you use $
for.
So you have:
map (length . filter (==4)) [[1,4],[4,3],[1,4,4,3]]
Alternatively, this would work also:
map (\x -> length $ filter (==4) x) [[1,4],[4,3],[1,4,4,3]]
but notice in this case you're applying filter (==4) x
to length
and filter (==4) x
is a value itself, not a function, so $
is the correct composition operator.
But I'd argue the former is better Haskell style.
Upvotes: 7