diff --git a/Data/Cache/LRU/Internal.hs b/Data/Cache/LRU/Internal.hs
--- a/Data/Cache/LRU/Internal.hs
+++ b/Data/Cache/LRU/Internal.hs
@@ -17,18 +17,18 @@
 
 -- | Stores the information that makes up an LRU cache
 data LRU key val = LRU {
-      first :: Maybe key -- ^ the key of the most recently accessed entry
-    , last :: Maybe key -- ^ the key of the least recently accessed entry
-    , maxSize :: Int -- ^ the maximum size of the LRU cache
-    , content :: Map key (LinkedVal key val) -- ^ the backing 'Map'
+      first :: !(Maybe key) -- ^ the key of the most recently accessed entry
+    , last :: !(Maybe key) -- ^ the key of the least recently accessed entry
+    , maxSize :: !Int -- ^ the maximum size of the LRU cache
+    , content :: !(Map key (LinkedVal key val)) -- ^ the backing 'Map'
     } deriving Eq
 
 -- | The values stored in the Map of the LRU cache.  They embed a
 -- doubly-linked list through the values of the 'Map'.
 data LinkedVal key val = Link {
       value :: val -- ^ The actual value
-    , prev :: Maybe key -- ^ the key of the value before this one
-    , next :: Maybe key -- ^ the key of the value after this one
+    , prev :: !(Maybe key) -- ^ the key of the value before this one
+    , next :: !(Maybe key) -- ^ the key of the value after this one
     } deriving Eq
 
 -- | Make an LRU.  The LRU is guaranteed to not grow above the
diff --git a/MemTest.hs b/MemTest.hs
new file mode 100644
--- /dev/null
+++ b/MemTest.hs
@@ -0,0 +1,25 @@
+import Prelude hiding ( lookup )
+
+import Control.Monad
+import Control.Concurrent
+import Data.IORef
+
+import Data.Cache.LRU.IO.Internal
+
+main :: IO ()
+main = do
+  v1 <- newAtomicLRU 10 -- for endless inserts
+  v2 <- newAtomicLRU 10 -- for endless lookups (miss)
+  v3 <- newAtomicLRU 10 -- for endless lookups (hit)
+
+  counter <- newIORef (0 :: Int)
+
+  insert 1 "bar" v3
+
+  forever $ do
+         c <- readIORef counter
+         writeIORef counter $ c + 1
+
+         insert c (show c) v1
+         lookup (1 :: Int) v2
+         lookup (1 :: Int) v3
diff --git a/OpTest.hs b/OpTest.hs
new file mode 100644
--- /dev/null
+++ b/OpTest.hs
@@ -0,0 +1,98 @@
+{-# LANGUAGE FlexibleInstances #-}
+import Prelude hiding ( lookup )
+
+import Control.Monad
+import Control.Monad.Exception.Synchronous
+
+import Data.Cache.LRU.Internal
+
+import Test.QuickCheck
+    ( Arbitrary(..)
+    , Args(..)
+    , choose
+    , oneof
+    , shrinkNothing
+    , quickCheckWith
+    , stdArgs
+    )
+import Test.QuickCheck.Property ( Result(..), result, succeeded )
+
+data Action key val = Insert key val
+                    | Lookup key
+                    | Delete key
+                      deriving (Show, Eq)
+
+instance Arbitrary (Action Int Int) where
+    arbitrary = oneof [ins, look, del]
+        where ins = liftM2 Insert key $ choose (100, 104)
+              look = liftM Lookup key
+              del = liftM Delete key
+              key = choose (1, 10)
+
+    shrink = shrinkNothing
+
+newtype History key val = H (Int, [Action key val] -> [Action key val])
+
+instance Arbitrary (History Int Int) where
+    arbitrary = liftM2 (curry H) s h
+        where s = choose (1, 5)
+              h = liftM (++) arbitrary
+
+    shrink (H (k, h)) = map (H . (,) k . (++)) . drops . h $ []
+        where drops [] = []
+              drops (x:xs) = xs:[x:ys | ys <- drops xs]
+
+instance (Show key, Show val) => Show (History key val) where
+    show (H (k, h)) = show (k, h [])
+
+execute :: (Ord key, Eq val, Show key, Show val) => History key val
+        -> Exceptional String (LRU key val)
+execute (H (k, h)) = execute' (h []) (newLRU k)
+    where
+      execute' [] lru = return lru
+      execute' (x:xs) lru = executeA x lru >>= execute' xs
+
+      execA' key val lru lru' = do
+        when (not . valid $ lru') $ throw "not valid"
+
+        let pre = toList lru
+            post = toList lru'
+
+            naive = (key, val) : filter ((key /=) . fst) pre
+            projected = if length naive <= k then naive else init naive
+        when (projected /= post) $ throw "unexpected result"
+
+        return lru'
+
+      executeA (Delete key) lru = do
+        let (lru', present) = delete key lru
+        when (not . valid $ lru') $ throw "not valid"
+
+        let pre = toList lru
+            post = toList lru'
+            projected = filter ((key /=) . fst) pre
+            shouldShorten = length projected /= length pre
+
+        when (present /= shouldShorten) $ throw "unexpected resulting bool"
+        when (projected /= post) $ throw "unexpected resulting lru"
+        return lru'
+
+      executeA (Insert key val) lru = execA' key val lru $ insert key val lru
+
+      executeA (Lookup key) lru = case mVal of
+                                    Nothing -> checkSame
+                                    Just val -> execA' key val lru lru'
+          where (lru', mVal) = lookup key lru
+                checkSame = do when (toList lru /= toList lru') $
+                                    throw "unexpected result"
+                               return lru'
+
+executesProperly :: History Int Int -> Result
+executesProperly h = case execute h of
+                       Success _ -> succeeded
+                       Exception e -> result { ok = Just False
+                                             , reason = e
+                                             }
+
+main :: IO ()
+main = quickCheckWith stdArgs { maxSuccess = 1000 } executesProperly
diff --git a/TestDriver.hs b/TestDriver.hs
deleted file mode 100644
--- a/TestDriver.hs
+++ /dev/null
@@ -1,98 +0,0 @@
-{-# LANGUAGE FlexibleInstances #-}
-import Prelude hiding ( lookup )
-
-import Control.Monad
-import Control.Monad.Exception.Synchronous
-
-import Data.Cache.LRU.Internal
-
-import Test.QuickCheck
-    ( Arbitrary(..)
-    , Args(..)
-    , choose
-    , oneof
-    , shrinkNothing
-    , quickCheckWith
-    , stdArgs
-    )
-import Test.QuickCheck.Property ( Result(..), result, succeeded )
-
-data Action key val = Insert key val
-                    | Lookup key
-                    | Delete key
-                      deriving (Show, Eq)
-
-instance Arbitrary (Action Int Int) where
-    arbitrary = oneof [ins, look, del]
-        where ins = liftM2 Insert key $ choose (100, 104)
-              look = liftM Lookup key
-              del = liftM Delete key
-              key = choose (1, 10)
-
-    shrink = shrinkNothing
-
-newtype History key val = H (Int, [Action key val] -> [Action key val])
-
-instance Arbitrary (History Int Int) where
-    arbitrary = liftM2 (curry H) s h
-        where s = choose (1, 5)
-              h = liftM (++) arbitrary
-
-    shrink (H (k, h)) = map (H . (,) k . (++)) . drops . h $ []
-        where drops [] = []
-              drops (x:xs) = xs:[x:ys | ys <- drops xs]
-
-instance (Show key, Show val) => Show (History key val) where
-    show (H (k, h)) = show (k, h [])
-
-execute :: (Ord key, Eq val, Show key, Show val) => History key val
-        -> Exceptional String (LRU key val)
-execute (H (k, h)) = execute' (h []) (newLRU k)
-    where
-      execute' [] lru = return lru
-      execute' (x:xs) lru = executeA x lru >>= execute' xs
-
-      execA' key val lru lru' = do
-        when (not . valid $ lru') $ throw "not valid"
-
-        let pre = toList lru
-            post = toList lru'
-
-            naive = (key, val) : filter ((key /=) . fst) pre
-            projected = if length naive <= k then naive else init naive
-        when (projected /= post) $ throw "unexpected result"
-
-        return lru'
-
-      executeA (Delete key) lru = do
-        let (lru', present) = delete key lru
-        when (not . valid $ lru') $ throw "not valid"
-
-        let pre = toList lru
-            post = toList lru'
-            projected = filter ((key /=) . fst) pre
-            shouldShorten = length projected /= length pre
-
-        when (present /= shouldShorten) $ throw "unexpected resulting bool"
-        when (projected /= post) $ throw "unexpected resulting lru"
-        return lru'
-
-      executeA (Insert key val) lru = execA' key val lru $ insert key val lru
-
-      executeA (Lookup key) lru = case mVal of
-                                    Nothing -> checkSame
-                                    Just val -> execA' key val lru lru'
-          where (lru', mVal) = lookup key lru
-                checkSame = do when (toList lru /= toList lru') $
-                                    throw "unexpected result"
-                               return lru'
-
-executesProperly :: History Int Int -> Result
-executesProperly h = case execute h of
-                       Success _ -> succeeded
-                       Exception e -> result { ok = Just False
-                                             , reason = e
-                                             }
-
-main :: IO ()
-main = quickCheckWith stdArgs { maxSuccess = 1000 } executesProperly
diff --git a/lrucache.cabal b/lrucache.cabal
--- a/lrucache.cabal
+++ b/lrucache.cabal
@@ -1,5 +1,5 @@
 Name:                lrucache
-Version:             0.2
+Version:             0.2.0.1
 Synopsis:            a simple, pure LRU cache
 License:             BSD3
 License-file:        LICENSE
@@ -19,6 +19,10 @@
         .
         Version History:
         .
+        0.2.0.1 - Increase strictness slightly.
+                  Remove cabal target for test executable.
+                  (Just include test sources instead.)
+        .
         0.2 - Added an Eq instance for LRU.
               Added strictness to eliminate space leaks in common use patterns.
         .
@@ -31,14 +35,11 @@
 
 Extra-source-files:
         README
-        TestDriver.hs
+        MemTest.hs
+        OpTest.hs
 
 Cabal-version:       >=1.6
 
-Flag Test
-  Description: Build test executables
-  Default: False
-
 Library
   Exposed-modules:
         Data.Cache.LRU
@@ -47,22 +48,7 @@
         Data.Cache.LRU.IO.Internal
 
   Build-depends:
-        base > 4 && < 5,
-        containers > 0.2 && < 0.4
-
-  GHC-Options:             -Wall
-
-
-Executable test
-  if flag(test)
-    Buildable: True
-
-    Build-Depends:
-        explicit-exception == 0.1.*,
-        QuickCheck == 2.1.*
-
-  else
-    Buildable: False
+        base >= 4 && < 5,
+        containers >= 0.2 && < 0.4
 
-  Main-is:                 TestDriver.hs
   GHC-Options:             -Wall
