Skip to content

Commit a9f7cc8

Browse files
committed
Better find behaviour and performance
This will result in `find` returning the first value to match a predicate rather than the last, and now the predicate is only run until the first match rather than on every item in the structure.
1 parent 1ada6db commit a9f7cc8

File tree

2 files changed

+9
-3
lines changed

2 files changed

+9
-3
lines changed

src/Data/Foldable.purs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,10 @@ notElem x = not <<< elem x
271271

272272
-- | Try to find an element in a data structure which satisfies a predicate.
273273
find :: forall a f. Foldable f => (a -> Boolean) -> f a -> Maybe a
274-
find p = foldl (\r x -> if p x then Just x else r) Nothing
274+
find p = foldl go Nothing
275+
where
276+
go Nothing x | p x = Just x
277+
go r _ = r
275278

276279
-- | Find the largest element of a structure, according to its `Ord` instance.
277280
maximum :: forall a f. (Ord a, Foldable f) => f a -> Maybe a

test/Main.purs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import Control.Monad.Eff.Console (CONSOLE, log)
88
import Data.Bifoldable (class Bifoldable, bifoldl, bifoldr, bifoldMap, bifoldrDefault, bifoldlDefault, bifoldMapDefaultR, bifoldMapDefaultL)
99
import Data.Bifunctor (class Bifunctor, bimap)
1010
import Data.Bitraversable (class Bitraversable, bisequenceDefault, bitraverse, bisequence, bitraverseDefault)
11-
import Data.Foldable (class Foldable, foldl, foldr, foldMap, foldrDefault, foldlDefault, foldMapDefaultR, foldMapDefaultL, minimumBy, minimum, maximumBy, maximum)
11+
import Data.Foldable (class Foldable, foldl, foldr, foldMap, foldrDefault, foldlDefault, foldMapDefaultR, foldMapDefaultL, minimumBy, minimum, maximumBy, maximum, find)
1212
import Data.Function (on)
1313
import Data.Int (toNumber)
1414
import Data.Maybe (Maybe(..))
@@ -77,6 +77,10 @@ main = do
7777
log "Test bisequenceDefault"
7878
testBitraversableIOrWith BSD
7979

80+
log "Test find"
81+
assert $ find (_ == 10) [1, 5, 10] == Just 10
82+
assert $ find (\x -> x `mod` 2 == 0) [1, 4, 10] == Just 4
83+
8084
log "Test maximum"
8185
assert $ maximum (arrayFrom1UpTo 10) == Just 10
8286

@@ -339,4 +343,3 @@ instance bitraversableBTD :: Bitraversable BitraverseDefault where
339343
instance bitraversableBSD :: Bitraversable BisequenceDefault where
340344
bitraverse f g (BSD m) = map BSD (bitraverse f g m)
341345
bisequence m = bisequenceDefault m
342-

0 commit comments

Comments
 (0)