diff options
author | Sylvain Henry <sylvain@haskus.fr> | 2021-03-05 15:04:59 +0100 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2021-03-14 12:57:40 -0400 |
commit | 87ae062ab8a73430308f4ea5967e76bc384e5a76 (patch) | |
tree | c3011e4c99d7076dcdd973bf02a05eb246a9aa63 | |
parent | d412cd108b2617cb3d2837994c7f39b5ba0b625d (diff) | |
download | haskell-87ae062ab8a73430308f4ea5967e76bc384e5a76.tar.gz |
Compute length only once in foldBal
-rw-r--r-- | compiler/GHC/Tc/Deriv/Generics.hs | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/compiler/GHC/Tc/Deriv/Generics.hs b/compiler/GHC/Tc/Deriv/Generics.hs index 5a9e329ae2..8b0899e38a 100644 --- a/compiler/GHC/Tc/Deriv/Generics.hs +++ b/compiler/GHC/Tc/Deriv/Generics.hs @@ -900,10 +900,17 @@ nlHsCompose x y = compose_RDR `nlHsApps` [x, y] -- | Variant of foldr for producing balanced lists foldBal :: (a -> a -> a) -> a -> [a] -> a -foldBal _ x [] = x -foldBal _ _ [y] = y -foldBal op x l = let (a,b) = splitAt (length l `div` 2) l - in foldBal op x a `op` foldBal op x b +{-# INLINE foldBal #-} -- inlined to produce specialised code for each op +foldBal op0 x0 xs0 = fold_bal op0 x0 (length xs0) xs0 + where + fold_bal op x !n xs = case xs of + [] -> x + [a] -> a + _ -> let !nl = n `div` 2 + !nr = n - nl + (l,r) = splitAt nl xs + in fold_bal op x nl l + `op` fold_bal op x nr r {- Note [Generics and unlifted types] |