summaryrefslogtreecommitdiff
path: root/libraries
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2014-06-17 11:47:40 +0100
committerSimon Marlow <marlowsd@gmail.com>2014-06-17 11:47:40 +0100
commit00fc4ba2363b466d1178ae6bcaec628c9cde4758 (patch)
tree9f8a40940b43ba97ed86c9522c5cba72f0d7bd4a /libraries
parent836981c7dec5c794ca94408468535cc018dc2e82 (diff)
downloadhaskell-00fc4ba2363b466d1178ae6bcaec628c9cde4758.tar.gz
Optimise the Typeable instance for type app a bit, and add a perf test
Test Plan: validate Reviewers: simonpj, austin Subscribers: simonmar, relrod Differential Revision: https://phabricator.haskell.org/D20
Diffstat (limited to 'libraries')
-rw-r--r--libraries/base/Data/Typeable/Internal.hs17
1 files changed, 14 insertions, 3 deletions
diff --git a/libraries/base/Data/Typeable/Internal.hs b/libraries/base/Data/Typeable/Internal.hs
index 5b1cde4347..a09d4ad1b9 100644
--- a/libraries/base/Data/Typeable/Internal.hs
+++ b/libraries/base/Data/Typeable/Internal.hs
@@ -1,4 +1,5 @@
{-# LANGUAGE Unsafe #-}
+{-# LANGUAGE BangPatterns #-}
-----------------------------------------------------------------------------
-- |
@@ -263,9 +264,19 @@ type Typeable7 (a :: * -> * -> * -> * -> * -> * -> * -> *) = Typeable a
-- | Kind-polymorphic Typeable instance for type application
instance (Typeable s, Typeable a) => Typeable (s a) where
- typeRep# = \_ -> rep
- where rep = typeRep# (proxy# :: Proxy# s)
- `mkAppTy` typeRep# (proxy# :: Proxy# a)
+ typeRep# = \_ -> rep -- Note [Memoising typeOf]
+ where !ty1 = typeRep# (proxy# :: Proxy# s)
+ !ty2 = typeRep# (proxy# :: Proxy# a)
+ !rep = ty1 `mkAppTy` ty2
+
+{- Note [Memoising typeOf]
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+See #3245, #9203
+
+IMPORTANT: we don't want to recalculate the TypeRep once per call with
+the proxy argument. This is what went wrong in #3245 and #9203. So we
+help GHC by manually keeping the 'rep' *outside* the lambda.
+-}
----------------- Showing TypeReps --------------------