Number of elements in Haskell in pointfree style
문제
I want to define a function that computes the number of elements in a list that satisfy a given predicate:
number_of_elements :: (a -> Bool) -> [a] -> Int
number_of_elements f xs = length (filter f xs)
For example:
number_of_elements (==2) [2,1,54,1,2]
should return 2.
We can write it shorter:
number_of_elements f = length . filter f
Is it possible to write it without f parameter?
해결책
Sure it is:
number_of_elements = (length .) . filter
다른 팁
I don't think you can get more readable than the what you suggested. However, just for the fun of it you can do this:
numberOfElements = (.) (.) (.) length filter
or
(.:) = (.) . (.)
numberOfElements = length .: filter
You might like to read about Semantic Editor Combinators. Take the result
combinator from there:
result :: (output -> output') -> (input -> output) -> (input -> output')
result = (.)
The result
combinator takes a function and applies it to the result of another function. Now, looking at the functions we have:
filter :: (a -> Bool) -> [a] -> [a]
length :: [a] -> Int
Now, length
applies to [a]
's; which, it happens, is the result type of functions of the form foo :: [a] -> [a]
. So,
result length :: ([a] -> [a]) -> ([a] -> Int)
But the result of filter
is exactly an [a] -> [a]
function, so we want to apply result length
to the result of filter
:
number_of_elements = result (result length) filter