Haskell中无点样式的元素数量

时间:2011-12-23 22:02:17

标签: haskell filter pointfree

我想定义一个函数来计算列表中满足给定谓词的元素数量:

  number_of_elements :: (a -> Bool) -> [a] -> Int
  number_of_elements f xs = length (filter f xs)

例如:

  number_of_elements (==2) [2,1,54,1,2]

应该返回 2

我们可以写得更短:

  number_of_elements f = length . filter f

是否可以在没有 f 参数的情况下编写它?

3 个答案:

答案 0 :(得分:17)

当然是:

number_of_elements = (length .) . filter

答案 1 :(得分:12)

我认为你不能比你建议的更具可读性。但是,只是为了它的乐趣,你可以这样做:

numberOfElements = (.) (.) (.) length filter

(.:) = (.) . (.)
numberOfElements = length .: filter

答案 2 :(得分:7)

您可能希望了解Semantic Editor Combinators。从那里取result组合器:

result :: (output -> output') -> (input -> output) -> (input -> output')
result = (.)

result组合器接受一个函数并将其应用于另一个函数的结果。现在,看看我们的功能:

filter :: (a -> Bool) -> [a] -> [a]
length :: [a] -> Int

现在,length适用于[a];它发生的是foo :: [a] -> [a]形式的函数的结果类型。所以,

result length :: ([a] -> [a]) -> ([a] -> Int)

filter的结果恰好是[a] -> [a]函数,因此我们要将result length应用于filter的结果:

number_of_elements = result (result length) filter