summaryrefslogtreecommitdiff
path: root/compiler/utils/Util.hs
diff options
context:
space:
mode:
authorRyan Scott <ryan.gl.scott@gmail.com>2017-06-02 13:12:11 -0400
committerBen Gamari <ben@smart-cactus.org>2017-06-02 13:12:13 -0400
commita786b136f48dfcf907dad55bcdbc4fcd247f2794 (patch)
tree9c6abee43aa398fdd8168b1cb7bd2d3fb5e6bacf /compiler/utils/Util.hs
parent811a2986475d88f73bb22b4600970039e1b582d6 (diff)
downloadhaskell-a786b136f48dfcf907dad55bcdbc4fcd247f2794.tar.gz
Use lengthIs and friends in more places
While investigating #12545, I discovered several places in the code that performed length-checks like so: ``` length ts == 4 ``` This is not ideal, since the length of `ts` could be much longer than 4, and we'd be doing way more work than necessary! There are already a slew of helper functions in `Util` such as `lengthIs` that are designed to do this efficiently, so I found every place where they ought to be used and did just that. I also defined a couple more utility functions for list length that were common patterns (e.g., `ltLength`). Test Plan: ./validate Reviewers: austin, hvr, goldfire, bgamari, simonmar Reviewed By: bgamari, simonmar Subscribers: goldfire, rwbarton, thomie Differential Revision: https://phabricator.haskell.org/D3622
Diffstat (limited to 'compiler/utils/Util.hs')
-rw-r--r--compiler/utils/Util.hs38
1 files changed, 36 insertions, 2 deletions
diff --git a/compiler/utils/Util.hs b/compiler/utils/Util.hs
index a4bc8d4653..35a6340fd4 100644
--- a/compiler/utils/Util.hs
+++ b/compiler/utils/Util.hs
@@ -36,9 +36,10 @@ module Util (
foldl1', foldl2, count, all2,
- lengthExceeds, lengthIs, lengthAtLeast,
+ lengthExceeds, lengthIs, lengthIsNot,
+ lengthAtLeast, lengthAtMost, lengthLessThan,
listLengthCmp, atLength,
- equalLength, compareLength, leLength,
+ equalLength, neLength, compareLength, leLength, ltLength,
isSingleton, only, singleton,
notNull, snocView,
@@ -494,6 +495,7 @@ lengthExceeds lst n
| otherwise
= atLength notNull False lst n
+-- | @(lengthAtLeast xs n) = (length xs >= n)@
lengthAtLeast :: [a] -> Int -> Bool
lengthAtLeast = atLength (const True) False
@@ -505,6 +507,24 @@ lengthIs lst n
| otherwise
= atLength null False lst n
+-- | @(lengthIsNot xs n) = (length xs /= n)@
+lengthIsNot :: [a] -> Int -> Bool
+lengthIsNot lst n
+ | n < 0 = True
+ | otherwise = atLength notNull True lst n
+
+-- | @(lengthAtMost xs n) = (length xs <= n)@
+lengthAtMost :: [a] -> Int -> Bool
+lengthAtMost lst n
+ | n < 0
+ = False
+ | otherwise
+ = atLength null True lst n
+
+-- | @(lengthLessThan xs n) == (length xs < n)@
+lengthLessThan :: [a] -> Int -> Bool
+lengthLessThan = atLength (const False) True
+
listLengthCmp :: [a] -> Int -> Ordering
listLengthCmp = atLength atLen atEnd
where
@@ -514,10 +534,17 @@ listLengthCmp = atLength atLen atEnd
atLen _ = GT
equalLength :: [a] -> [b] -> Bool
+-- ^ True if length xs == length ys
equalLength [] [] = True
equalLength (_:xs) (_:ys) = equalLength xs ys
equalLength _ _ = False
+neLength :: [a] -> [b] -> Bool
+-- ^ True if length xs /= length ys
+neLength [] [] = False
+neLength (_:xs) (_:ys) = neLength xs ys
+neLength _ _ = True
+
compareLength :: [a] -> [b] -> Ordering
compareLength [] [] = EQ
compareLength (_:xs) (_:ys) = compareLength xs ys
@@ -531,6 +558,13 @@ leLength xs ys = case compareLength xs ys of
EQ -> True
GT -> False
+ltLength :: [a] -> [b] -> Bool
+-- ^ True if length xs < length ys
+ltLength xs ys = case compareLength xs ys of
+ LT -> True
+ EQ -> False
+ GT -> False
+
----------------------------
singleton :: a -> [a]
singleton x = [x]