0

これが私の機能です。正の値をチェックし、それらを 1 に変更して合計します。

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

lengthとのみを使用せずfoldrに正の値をカウントするより良い戦略はありmapますfilterか?

4

2 に答える 2

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通りの方法で回答できる可能性がありますが、最も簡単な方法はとを使用することfilterですlength

于 2012-12-07T16:56:55.767 に答える
5

もちろん、次のように直接数えるだけfoldrです:

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

lengthまたは再実装foldr:

countPositive = foldr (const succ) 0 . filter (>0)
于 2012-12-07T16:28:27.117 に答える