Better than counting the length of a list of units.

I sometimes find that I am writing code as follows:

someFunc :: Foo -> Int someFunc foo = length $ do x <- someList guard someGuard return () 

Or equivalently:

 someFunc foo = length [() | x <- someList, someGuard] 

Is there a better way to do such a calculation? More effective? More readable? More idiomatic?

+6
source share
2 answers

If you find yourself repeatedly programming a template, you need to record a higher-order function to encapsulate this template. You can use the body that you have, but in order to be absolutely sure that your code does not stand out, I would recommend using foldl and a strict application of the increment operator:

 numberSatisfying :: Integral n => (a -> Bool) -> [a] -> n numberSatisfying p = foldl (\nx -> if px then (+1) $! n else n) 0 

I used QuickCheck to validate this code equivalent to your source code. (And yes, it's pretty cool that QuickCheck will check with random predicates.)

+6
source

Primo

 guard someGuard return () 

is redundant, guard already returns () if the condition is true. Then I suppose that someGuard really depends on x , otherwise it would be if someGuard then length someList else 0 . The usual way to record is

 someFunc foo = filter (\x -> someGuard) someList 

if the situation is really as simple as your example looks. For more complex situations, using one of the styles in your example is the most direct way. I believe that doing notation is preferable if things get very complicated.

+8
source

Source: https://habr.com/ru/post/906256/


All Articles