summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Pickering <matthewtpickering@gmail.com>2023-02-09 16:17:05 +0000
committerMatthew Pickering <matthewtpickering@gmail.com>2023-02-17 09:37:16 +0000
commitbe0b7209c6aef22798fc4ba7baacd2099b5cb494 (patch)
tree97ff9900ff2afea0270f4d18afe3970691407ff3
parentc6a967d9545ef5577514466f3fa6894f2899aff8 (diff)
downloadhaskell-wip/generic-inlinable.tar.gz
Add INLINABLE pragmas to `generic*` functions in Data.OldListwip/generic-inlinable
These functions are * recursive * overloaded So it's important to add an `INLINABLE` pragma to each so that they can be specialised at the use site when the specific numeric type is known. Adding these pragmas improves the LazyText replicate benchmark (see https://gitlab.haskell.org/ghc/ghc/-/issues/22886#note_481020) https://github.com/haskell/core-libraries-committee/issues/129
-rw-r--r--libraries/base/Data/OldList.hs6
-rw-r--r--libraries/base/changelog.md1
2 files changed, 7 insertions, 0 deletions
diff --git a/libraries/base/Data/OldList.hs b/libraries/base/Data/OldList.hs
index 211978dadd..ef5960542d 100644
--- a/libraries/base/Data/OldList.hs
+++ b/libraries/base/Data/OldList.hs
@@ -842,6 +842,7 @@ strictGenericLength l = gl l 0
where
gl [] a = a
gl (_:xs) a = let a' = a + 1 in a' `seq` gl xs a'
+{-# INLINABLE strictGenericLength #-}
-- | The 'genericTake' function is an overloaded version of 'take', which
-- accepts any 'Integral' value as the number of elements to take.
@@ -849,6 +850,7 @@ genericTake :: (Integral i) => i -> [a] -> [a]
genericTake n _ | n <= 0 = []
genericTake _ [] = []
genericTake n (x:xs) = x : genericTake (n-1) xs
+{-# INLINABLE genericTake #-}
-- | The 'genericDrop' function is an overloaded version of 'drop', which
-- accepts any 'Integral' value as the number of elements to drop.
@@ -856,6 +858,7 @@ genericDrop :: (Integral i) => i -> [a] -> [a]
genericDrop n xs | n <= 0 = xs
genericDrop _ [] = []
genericDrop n (_:xs) = genericDrop (n-1) xs
+{-# INLINABLE genericDrop #-}
-- | The 'genericSplitAt' function is an overloaded version of 'splitAt', which
@@ -865,6 +868,7 @@ genericSplitAt n xs | n <= 0 = ([],xs)
genericSplitAt _ [] = ([],[])
genericSplitAt n (x:xs) = (x:xs',xs'') where
(xs',xs'') = genericSplitAt (n-1) xs
+{-# INLINABLE genericSplitAt #-}
-- | The 'genericIndex' function is an overloaded version of '!!', which
-- accepts any 'Integral' value as the index.
@@ -874,11 +878,13 @@ genericIndex (_:xs) n
| n > 0 = genericIndex xs (n-1)
| otherwise = errorWithoutStackTrace "List.genericIndex: negative argument."
genericIndex _ _ = errorWithoutStackTrace "List.genericIndex: index too large."
+{-# INLINABLE genericIndex #-}
-- | The 'genericReplicate' function is an overloaded version of 'replicate',
-- which accepts any 'Integral' value as the number of repetitions to make.
genericReplicate :: (Integral i) => i -> a -> [a]
genericReplicate n x = genericTake n (repeat x)
+{-# INLINABLE genericReplicate #-}
-- | The 'zip4' function takes four lists and returns a list of
-- quadruples, analogous to 'zip'.
diff --git a/libraries/base/changelog.md b/libraries/base/changelog.md
index b102de449c..bef533f263 100644
--- a/libraries/base/changelog.md
+++ b/libraries/base/changelog.md
@@ -6,6 +6,7 @@
types significantly.
* Refactor `generalCategory` to stop very large literal string being inlined to call-sites.
([CLC proposal #130](https://github.com/haskell/core-libraries-committee/issues/130))
+ * Add INLINABLE pragmas to `generic*` functions in Data.OldList ([CLC proposal #129](https://github.com/haskell/core-libraries-committee/issues/130))
## 4.18.0.0 *TBA*