summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoachim Breitner <mail@joachim-breitner.de>2015-04-16 14:49:23 +0200
committerAustin Seipp <austin@well-typed.com>2015-05-06 07:37:43 -0500
commit7ea4e243b8a204cc2fff813249851e5242b40daf (patch)
tree8633d6dfd05b4b18d39f1126819f4cf8a8a75566
parentb324fac4e9769c963620ccfc645e0ee2890da5b7 (diff)
downloadhaskell-7ea4e243b8a204cc2fff813249851e5242b40daf.tar.gz
Make sure GHC.List.last is memory-efficient
by eta-expanding its definition so that GHC optmizes the foldl here. Also make sure that other uses of last go via foldl as well, to allow list fusion (tested in T9339). Fixes #10260. (cherry picked from commit 524ddbdad5816f77b7b719cac0671eebd3473616)
-rw-r--r--libraries/base/GHC/List.hs11
1 files changed, 9 insertions, 2 deletions
diff --git a/libraries/base/GHC/List.hs b/libraries/base/GHC/List.hs
index a712f9e4be..fcc89d3f8f 100644
--- a/libraries/base/GHC/List.hs
+++ b/libraries/base/GHC/List.hs
@@ -84,8 +84,15 @@ last [x] = x
last (_:xs) = last xs
last [] = errorEmptyList "last"
#else
--- use foldl to allow fusion
-last = foldl (\_ x -> x) (errorEmptyList "last")
+-- Use foldl to make last a good consumer.
+-- This will compile to good code for the actual GHC.List.last.
+-- (At least as long it is eta-expaned, otherwise it does not, #10260.)
+last xs = foldl (\_ x -> x) lastError xs
+{-# INLINE last #-}
+-- The inline pragma is required to make GHC remember the implementation via
+-- foldl.
+lastError :: a
+lastError = errorEmptyList "last"
#endif
-- | Return all the elements of a list except the last one.