문제

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
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top