我想定义一个函数来计算列表中满足给定谓词的元素数量:
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 参数的情况下编写它?
答案 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