diff --git a/Data/Cache/LRU/IO.hs b/Data/Cache/LRU/IO.hs
--- a/Data/Cache/LRU/IO.hs
+++ b/Data/Cache/LRU/IO.hs
@@ -3,6 +3,10 @@
 -- calls preserve the same semantics as those in "Data.Cache.LRU", but
 -- perform updates in place.
 --
+-- The interface this module provides is opaque.  If further control
+-- is desired, the "Data.Cache.LRU.IO.Internal" module can be used in
+-- combination with "Data.Cache.LRU.Internal".
+--
 -- (This implementation uses an MVar for coarse locking. It's unclear
 -- if anything else would give better performance, given that many
 -- calls alter the head of the access list.)
@@ -21,55 +25,4 @@
 
 import Prelude hiding ( lookup )
 
-import Control.Applicative ( (<$>) )
-import Control.Concurrent.MVar
-    ( MVar
-    , newMVar
-    , readMVar
-    , modifyMVar
-    , modifyMVar_
-    )
-
-import Data.Cache.LRU ( LRU )
-import qualified Data.Cache.LRU as LRU
-
--- | The opaque wrapper type
-newtype AtomicLRU key val = C (MVar (LRU key val))
-
--- | Make a new AtomicLRU with the given maximum size.
-newAtomicLRU :: Ord key => Int -- ^ the maximum size
-             -> IO (AtomicLRU key val)
-newAtomicLRU = fmap C . newMVar . LRU.newLRU
-
--- | Build a new LRU from the given maximum size and list of
--- contents. See 'LRU.fromList' for the semantics.
-fromList :: Ord key => Int -- ^ the maximum size
-            -> [(key, val)] -> IO (AtomicLRU key val)
-fromList s l = fmap C . newMVar $ LRU.fromList s l
-
--- | Retreive a list view of an AtomicLRU.  See 'LRU.toList' for the
--- semantics.
-toList :: Ord key => AtomicLRU key val -> IO [(key, val)]
-toList (C mvar) = LRU.toList <$> readMVar mvar
-
-maxSize :: AtomicLRU key val -> IO Int
-maxSize (C mvar) = LRU.maxSize <$> readMVar mvar
-
--- | Insert a key/value pair into an AtomicLRU.  See 'LRU.insert' for
--- the semantics.
-insert :: Ord key => key -> val -> AtomicLRU key val -> IO ()
-insert key val (C mvar) = modifyMVar_ mvar $ return . LRU.insert key val
-
--- | Look up a key in an AtomicLRU. See 'LRU.lookup' for the
--- semantics.
-lookup :: Ord key => key -> AtomicLRU key val -> IO (Maybe val)
-lookup key (C mvar) = modifyMVar mvar $ return . LRU.lookup key
-
--- | Remove an item from an AtomicLRU.  Returns whether the item was
--- present to be removed.
-delete :: (Ord key) => key -> AtomicLRU key val -> IO Bool
-delete key (C mvar) = modifyMVar mvar $ return . LRU.delete key
-
--- | Returns the number of elements the AtomicLRU currently contains.
-size :: AtomicLRU key val -> IO Int
-size (C mvar) = LRU.size <$> readMVar mvar
+import Data.Cache.LRU.IO.Internal
diff --git a/Data/Cache/LRU/IO/Internal.hs b/Data/Cache/LRU/IO/Internal.hs
new file mode 100644
--- /dev/null
+++ b/Data/Cache/LRU/IO/Internal.hs
@@ -0,0 +1,65 @@
+-- | This module contains a mutable wrapping of an LRU in the IO
+-- monad, providing atomic access in a concurrent environment.  All
+-- calls preserve the same semantics as those in "Data.Cache.LRU", but
+-- perform updates in place.
+--
+-- This module contains the internal implementation details.  It's
+-- possible to put an 'AtomicLRU' into a bad state with this module.
+-- It is highly recommended that the external interface,
+-- "Data.Cache.LRU.IO", be used instead.
+module Data.Cache.LRU.IO.Internal where
+
+import Prelude hiding ( lookup )
+
+import Control.Applicative ( (<$>) )
+import Control.Concurrent.MVar
+    ( MVar
+    , newMVar
+    , readMVar
+    , modifyMVar
+    , modifyMVar_
+    )
+
+import Data.Cache.LRU ( LRU )
+import qualified Data.Cache.LRU as LRU
+
+-- | The opaque wrapper type
+newtype AtomicLRU key val = C (MVar (LRU key val))
+
+-- | Make a new AtomicLRU with the given maximum size.
+newAtomicLRU :: Ord key => Int -- ^ the maximum size
+             -> IO (AtomicLRU key val)
+newAtomicLRU = fmap C . newMVar . LRU.newLRU
+
+-- | Build a new LRU from the given maximum size and list of
+-- contents. See 'LRU.fromList' for the semantics.
+fromList :: Ord key => Int -- ^ the maximum size
+            -> [(key, val)] -> IO (AtomicLRU key val)
+fromList s l = fmap C . newMVar $ LRU.fromList s l
+
+-- | Retreive a list view of an AtomicLRU.  See 'LRU.toList' for the
+-- semantics.
+toList :: Ord key => AtomicLRU key val -> IO [(key, val)]
+toList (C mvar) = LRU.toList <$> readMVar mvar
+
+maxSize :: AtomicLRU key val -> IO Int
+maxSize (C mvar) = LRU.maxSize <$> readMVar mvar
+
+-- | Insert a key/value pair into an AtomicLRU.  See 'LRU.insert' for
+-- the semantics.
+insert :: Ord key => key -> val -> AtomicLRU key val -> IO ()
+insert key val (C mvar) = modifyMVar_ mvar $ return . LRU.insert key val
+
+-- | Look up a key in an AtomicLRU. See 'LRU.lookup' for the
+-- semantics.
+lookup :: Ord key => key -> AtomicLRU key val -> IO (Maybe val)
+lookup key (C mvar) = modifyMVar mvar $ return . LRU.lookup key
+
+-- | Remove an item from an AtomicLRU.  Returns whether the item was
+-- present to be removed.
+delete :: (Ord key) => key -> AtomicLRU key val -> IO Bool
+delete key (C mvar) = modifyMVar mvar $ return . LRU.delete key
+
+-- | Returns the number of elements the AtomicLRU currently contains.
+size :: AtomicLRU key val -> IO Int
+size (C mvar) = LRU.size <$> readMVar mvar
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
@@ -12,7 +12,6 @@
 
 import Prelude hiding ( last, lookup )
 
-import Data.Maybe ( maybe )
 import Data.Map ( Map )
 import qualified Data.Map as Map
 
diff --git a/lrucache.cabal b/lrucache.cabal
--- a/lrucache.cabal
+++ b/lrucache.cabal
@@ -1,6 +1,6 @@
 Name:                lrucache
-Version:             0.1.0.1
-Synopsis:            a simple pure LRU cache
+Version:             0.1.1
+Synopsis:            a simple, pure LRU cache
 License:             BSD3
 License-file:        LICENSE
 Author:              Carl Howells
@@ -11,11 +11,20 @@
 Category:            Data
 Build-type:          Simple
 Description:
-        This package contains a simple pure LRU cache, implemented in
+        This package contains a simple, pure LRU cache, implemented in
         terms of "Data.Map".
         .
         It also contains a mutable IO wrapper providing atomic updates to
         an LRU cache.
+        .
+        Version History:
+        .
+        0.1.1 - Add the Data.Cache.LRU.IO.Internal module.
+                Clean up build warnings on GHC 6.12.1.
+        .
+        0.1.0.1 - Minor refactoring
+        .
+        0.1 - First release
 
 Extra-source-files:
         README
@@ -30,12 +39,13 @@
 Library
   Exposed-modules:
         Data.Cache.LRU
-        Data.Cache.LRU.IO
         Data.Cache.LRU.Internal
+        Data.Cache.LRU.IO
+        Data.Cache.LRU.IO.Internal
 
   Build-depends:
-        base < 5,
-        containers
+        base > 4 && < 5,
+        containers > 0.2 && < 0.4
 
   GHC-Options:             -Wall
 
@@ -45,7 +55,6 @@
     Buildable: True
 
     Build-Depends:
-        base < 4.2,
         explicit-exception == 0.1.*,
         QuickCheck == 2.1.*
 
