summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHécate Moonlight <hecate+gitlab@glitchbra.in>2021-04-03 09:02:34 +0200
committerMarge Bot <ben+marge-bot@smart-cactus.org>2021-04-14 14:40:46 -0400
commit78ed7adf4f27ece8a50be94a7ee107c8e84ac81e (patch)
tree867466cf39f90a5ca1361aebba59c55b809b75be
parent726da09e76d0832b5aedd5b78624435695ac04e7 (diff)
downloadhaskell-78ed7adf4f27ece8a50be94a7ee107c8e84ac81e.tar.gz
Data.List strictness optimisations for maximumBy and minimumBy
follow-up from !4675
-rw-r--r--libraries/base/Data/List.hs35
1 files changed, 21 insertions, 14 deletions
diff --git a/libraries/base/Data/List.hs b/libraries/base/Data/List.hs
index 8ae1b9e14a..2e2b1efde4 100644
--- a/libraries/base/Data/List.hs
+++ b/libraries/base/Data/List.hs
@@ -712,13 +712,17 @@ insertBy cmp x ys@(y:ys')
--
-- >>> maximumBy (\x y -> compare (length x) (length y)) ["Hello", "World", "!", "Longest", "bar"]
-- "Longest"
-maximumBy :: (a -> a -> Ordering) -> [a] -> a
-maximumBy _ [] = errorWithoutStackTrace "List.maximumBy: empty list"
-maximumBy cmp xs = foldl1 maxBy xs
- where
- maxBy x y = case cmp x y of
- GT -> x
- _ -> y
+maximumBy :: (a -> a -> Ordering) -> [a] -> a
+maximumBy cmp = fromMaybe (errorWithoutStackTrace "maximumBy: empty structure")
+ . foldl' max' Nothing
+ where
+ max' mx y = Just $! case mx of
+ Nothing -> y
+ Just x -> case cmp x y of
+ GT -> x
+ _ -> y
+{-# INLINEABLE maximumBy #-}
+
-- | The 'minimumBy' function takes a comparison function and a list
-- and returns the least element of the list by the comparison function.
@@ -728,13 +732,16 @@ maximumBy cmp xs = foldl1 maxBy xs
--
-- >>> minimumBy (\x y -> compare (length x) (length y)) ["Hello", "World", "!", "Longest", "bar"]
-- "!"
-minimumBy :: (a -> a -> Ordering) -> [a] -> a
-minimumBy _ [] = errorWithoutStackTrace "List.minimumBy: empty list"
-minimumBy cmp xs = foldl1 minBy xs
- where
- minBy x y = case cmp x y of
- GT -> y
- _ -> x
+minimumBy :: (a -> a -> Ordering) -> [a] -> a
+minimumBy cmp = fromMaybe (errorWithoutStackTrace "minimumBy: empty structure")
+ . foldl' min' Nothing
+ where
+ min' mx y = Just $! case mx of
+ Nothing -> y
+ Just x -> case cmp x y of
+ GT -> y
+ _ -> x
+{-# INLINEABLE minimumBy #-}
-- | \(\mathcal{O}(n)\). The 'genericLength' function is an overloaded version
-- of 'length'. In particular, instead of returning an 'Int', it returns any