I need to return false if a test fails for more than 3 elements in a list. Is there anything I can to do optimize ?
isItemOk :: Integer -> Boolean
isItemOk = ( some costly opernation )
This is the function I am trying to optimize,
isListOk :: [Integer] -> Boolean
isListOk = 3 >= sum ( [ 1 | x <- [1.1000], isItemOk x ])
My attempt at optimization , assuming take if it finds 4 elements will not look for more.
isListOk :: [Integer] -> Boolean
isListOk = 3 >= sum ( take 4 [ 1 | x <- [1.1000], isItemOk x ])
Thanks.
You can just use
filterwith something that checks for failing elements, thentake 4and see how many elements you have withlength.Lazy evaluation means it won’t bother checking anything after finding those four, so you’re done. Of course, if the test fails for three or fewer elements, it’ll check the whole list, but there’s nothing you can do about that.
The important thing to avoid is something like “count the elements that fail the test”, or “filter and then get the length of the result”, or anything like that. Without using
takeor something similar first, doing that will force checking the entire list. This is a more general version of the “usenullor pattern matching to check for empty lists” advice often given to beginners. But it looks like you’re already avoiding that mistake!