2012-12-07 17 views
0

這是我的功能。它檢查正值,將它們更改爲一個值並對它們進行求和。計數正值

countPositive :: [Integer] -> Integer 
countPositive xs = foldr (+) 0 $ map (^0) (filter (>0) xs) 

有沒有更好的策略,而無需使用length只是foldrmapfilter算正面的價值觀?

回答

5

當然,只是直接與foldr盡數:

countPositive = foldr (\n count -> if n > 0 then count + 1 else count) 0 

或用foldr重新實現length

countPositive = foldr (const succ) 0 . filter (>0) 
+0

你能解釋一下const succ嗎? – nick

+0

'const succ = \ a - > succ = \ a n - > succ n = \ a n - > n + 1'。它忽略了列表中的元素(第一個參數)並且只是不斷遞增計數器(第二個參數)。 – huon

9

FOLDR似乎並不在這裏。你想foldl'來代替。這是我的解決方案:

countPos :: (Num a, Ord a) => [a] -> Int 
countPos = length . filter (> 0) 

當你不想使用length由於某種原因,你基本上只是重塑它:

countPos xs = sum (1 <$ filter (> 0) xs) 

或另一種方法:

countPos = foldl' (\x _ -> succ x) 0 . filter (> 0) 

有很多很多的方法可以做到這一點。如果100個人回答這個帖子,很可能你會得到100種不同的方式,但最簡單的方法是使用filterlength