diff options
author | Simon Peyton Jones <simonpj@microsoft.com> | 2014-05-13 10:55:33 +0100 |
---|---|---|
committer | Simon Peyton Jones <simonpj@microsoft.com> | 2014-08-28 11:14:11 +0100 |
commit | 2ef997b827a5630ad639b5283574a4273cae47ce (patch) | |
tree | 64add00120203447b1132d64f369950677b91a8d | |
parent | 949ad67e2f475864a405d214c3e02f2918931eb8 (diff) | |
download | haskell-2ef997b827a5630ad639b5283574a4273cae47ce.tar.gz |
Slightly improve fusion rules for 'take'
-rw-r--r-- | libraries/base/GHC/List.lhs | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/libraries/base/GHC/List.lhs b/libraries/base/GHC/List.lhs index 9b6cc2eb19..bcc5fea747 100644 --- a/libraries/base/GHC/List.lhs +++ b/libraries/base/GHC/List.lhs @@ -385,10 +385,17 @@ takeFoldr (I# n#) xs takeConst :: a -> Int# -> a takeConst x _ = x -{-# NOINLINE [0] takeFB #-} +{-# INLINE [0] takeFB #-} takeFB :: (a -> b -> b) -> b -> a -> (Int# -> b) -> Int# -> b -takeFB c n x xs m | isTrue# (m <=# 1#) = x `c` n - | otherwise = x `c` xs (m -# 1#) +-- The \m accounts for the fact that takeFB is used in a higher-order +-- way by takeFoldr, so it's better to inline. A good example is +-- take n (repeat x) +-- for which we get excellent code... but only if we inline takeFB +-- when given four arguments +takeFB c n x xs + = \ m -> if isTrue# (m <=# 1#) + then x `c` n + else x `c` xs (m -# 1#) {-# INLINE [0] take #-} take (I# n#) xs = takeUInt n# xs |