diff --git a/Data/ByteString/Interned.hs b/Data/ByteString/Interned.hs
deleted file mode 100644
--- a/Data/ByteString/Interned.hs
+++ /dev/null
@@ -1,6 +0,0 @@
-module Data.ByteString.Interned
-  ( InternedByteString(..)
-  ) where
-
-import Data.ByteString.Interned.Internal
-
diff --git a/Data/ByteString/Interned/Internal.hs b/Data/ByteString/Interned/Internal.hs
deleted file mode 100644
--- a/Data/ByteString/Interned/Internal.hs
+++ /dev/null
@@ -1,45 +0,0 @@
-{-# LANGUAGE TypeFamilies, FlexibleInstances #-}
-module Data.ByteString.Interned.Internal
-  ( InternedByteString(..)
-  ) where
-
-import Data.String
-import Data.Interned
-import Data.ByteString
-import Data.ByteString.Char8 as Char8
-import Data.Hashable
-import Data.Function (on)
-
-data InternedByteString = InternedByteString 
-  {-# UNPACK #-} !Id
-  {-# UNPACK #-} !ByteString
-
-instance IsString InternedByteString where
-  fromString = intern . Char8.pack
-
-instance Eq InternedByteString where
-  (==) = (==) `on` identity
-
-instance Ord InternedByteString where
-  compare = compare `on` identity
-
-instance Show InternedByteString where
-  showsPrec d (InternedByteString _ b) = showsPrec d b
-
-instance Interned InternedByteString where
-  type Uninterned InternedByteString = ByteString
-  data Description InternedByteString = DBS {-# UNPACK #-} !ByteString deriving (Eq) 
-  describe = DBS
-  identify = InternedByteString
-  identity (InternedByteString i _) = i
-  cache = ibsCache
-
-instance Uninternable InternedByteString where
-  unintern (InternedByteString _ b) = b 
-
-instance Hashable (Description InternedByteString) where
-  hash (DBS h) = hash h
-
-ibsCache :: Cache InternedByteString
-ibsCache = mkCache
-{-# NOINLINE ibsCache #-}
diff --git a/Data/Interned/ByteString.hs b/Data/Interned/ByteString.hs
new file mode 100644
--- /dev/null
+++ b/Data/Interned/ByteString.hs
@@ -0,0 +1,6 @@
+module Data.Interned.ByteString
+  ( InternedByteString
+  ) where
+
+import Data.Interned.Internal.ByteString
+
diff --git a/Data/Interned/Internal.hs b/Data/Interned/Internal.hs
--- a/Data/Interned/Internal.hs
+++ b/Data/Interned/Internal.hs
@@ -12,6 +12,7 @@
   , cacheSize
   , Id
   , intern
+  , recover
   ) where
 
 import Data.Hashable
@@ -36,6 +37,7 @@
 mkCache = result where
   result = Cache $ unsafePerformIO $ newMVar $ CacheState (seedIdentity result) HashMap.empty
 
+
 type Id = Int
 
 class ( Eq (Description t)
@@ -69,3 +71,11 @@
              return (CacheState (i + 1) (HashMap.insert dt wt m), t)
   remove = modifyMVar_ (getCache cache) $ 
     \ (CacheState i m) -> return $ CacheState i (HashMap.delete dt m)
+
+-- given a description, go hunting for an entry in the cache
+recover :: Interned t => Description t -> IO (Maybe t)
+recover dt = do
+  CacheState _ m <- readMVar $ getCache cache
+  case HashMap.lookup dt m of
+    Nothing -> return Nothing
+    Just wt -> deRefWeak wt
diff --git a/Data/Interned/Internal/ByteString.hs b/Data/Interned/Internal/ByteString.hs
new file mode 100644
--- /dev/null
+++ b/Data/Interned/Internal/ByteString.hs
@@ -0,0 +1,45 @@
+{-# LANGUAGE TypeFamilies, FlexibleInstances #-}
+module Data.Interned.Internal.ByteString
+  ( InternedByteString(..)
+  ) where
+
+import Data.String
+import Data.Interned
+import Data.ByteString
+import Data.ByteString.Char8 as Char8
+import Data.Hashable
+import Data.Function (on)
+
+data InternedByteString = InternedByteString 
+  {-# UNPACK #-} !Id
+  {-# UNPACK #-} !ByteString
+
+instance IsString InternedByteString where
+  fromString = intern . Char8.pack
+
+instance Eq InternedByteString where
+  (==) = (==) `on` identity
+
+instance Ord InternedByteString where
+  compare = compare `on` identity
+
+instance Show InternedByteString where
+  showsPrec d (InternedByteString _ b) = showsPrec d b
+
+instance Interned InternedByteString where
+  type Uninterned InternedByteString = ByteString
+  data Description InternedByteString = DBS {-# UNPACK #-} !ByteString deriving (Eq) 
+  describe = DBS
+  identify = InternedByteString
+  identity (InternedByteString i _) = i
+  cache = ibsCache
+
+instance Uninternable InternedByteString where
+  unintern (InternedByteString _ b) = b 
+
+instance Hashable (Description InternedByteString) where
+  hash (DBS h) = hash h
+
+ibsCache :: Cache InternedByteString
+ibsCache = mkCache
+{-# NOINLINE ibsCache #-}
diff --git a/Data/Interned/Internal/String.hs b/Data/Interned/Internal/String.hs
new file mode 100644
--- /dev/null
+++ b/Data/Interned/Internal/String.hs
@@ -0,0 +1,47 @@
+{-# LANGUAGE TypeFamilies, FlexibleInstances #-}
+module Data.Interned.Internal.String
+  ( InternedString(..)
+  ) where
+
+import Data.String
+import Data.Interned
+import Data.Hashable
+import Data.Foldable
+import Data.Function (on)
+
+data InternedString = IS 
+  {-# UNPACK #-} !Id
+  String
+
+instance IsString InternedString where
+  fromString = intern
+
+instance Eq InternedString where
+  (==) = (==) `on` identity
+
+instance Ord InternedString where
+  compare = compare `on` identity
+
+instance Show InternedString where
+  showsPrec d (IS _ b) = showsPrec d b
+
+instance Interned InternedString where
+  type Uninterned InternedString = String
+  data Description InternedString = Cons {-# UNPACK #-} !Char String | Nil
+    deriving (Eq) 
+  describe (c:cs) = Cons c cs
+  describe []     = Nil
+  identify = IS
+  identity (IS i _) = i
+  cache = stringCache
+
+instance Uninternable InternedString where
+  unintern (IS _ b) = b 
+
+instance Hashable (Description InternedString) where
+  hash (Cons c s) = foldl' hashWithSalt (hashWithSalt 0 c) s
+  hash Nil        = 0
+
+stringCache :: Cache InternedString
+stringCache = mkCache
+{-# NOINLINE stringCache #-}
diff --git a/Data/Interned/Internal/Text.hs b/Data/Interned/Internal/Text.hs
new file mode 100644
--- /dev/null
+++ b/Data/Interned/Internal/Text.hs
@@ -0,0 +1,44 @@
+{-# LANGUAGE TypeFamilies, FlexibleInstances #-}
+module Data.Interned.Internal.Text
+  ( InternedText(..)
+  ) where
+
+import Data.String
+import Data.Interned
+import Data.Text
+import Data.Hashable
+import Data.Function (on)
+
+data InternedText = InternedText 
+  {-# UNPACK #-} !Id
+  {-# UNPACK #-} !Text
+
+instance IsString InternedText where
+  fromString = intern . pack
+
+instance Eq InternedText where
+  (==) = (==) `on` identity
+
+instance Ord InternedText where
+  compare = compare `on` identity
+
+instance Show InternedText where
+  showsPrec d (InternedText _ b) = showsPrec d b
+
+instance Interned InternedText where
+  type Uninterned InternedText = Text
+  data Description InternedText = DT {-# UNPACK #-} !Text deriving (Eq) 
+  describe = DT
+  identify = InternedText
+  identity (InternedText i _) = i
+  cache = itCache
+
+instance Uninternable InternedText where
+  unintern (InternedText _ b) = b 
+
+instance Hashable (Description InternedText) where
+  hash (DT h) = hash h
+
+itCache :: Cache InternedText
+itCache = mkCache
+{-# NOINLINE itCache #-}
diff --git a/Data/Interned/String.hs b/Data/Interned/String.hs
new file mode 100644
--- /dev/null
+++ b/Data/Interned/String.hs
@@ -0,0 +1,5 @@
+module Data.Interned.String
+  ( InternedString
+  ) where
+
+import Data.Interned.Internal.String
diff --git a/Data/Interned/Text.hs b/Data/Interned/Text.hs
new file mode 100644
--- /dev/null
+++ b/Data/Interned/Text.hs
@@ -0,0 +1,5 @@
+module Data.Interned.Text
+  ( InternedText
+  ) where
+
+import Data.Interned.Internal.Text
diff --git a/Data/String/Interned.hs b/Data/String/Interned.hs
deleted file mode 100644
--- a/Data/String/Interned.hs
+++ /dev/null
@@ -1,5 +0,0 @@
-module Data.String.Interned
-  ( InternedString
-  ) where
-
-import Data.String.Interned.Internal
diff --git a/Data/String/Interned/Internal.hs b/Data/String/Interned/Internal.hs
deleted file mode 100644
--- a/Data/String/Interned/Internal.hs
+++ /dev/null
@@ -1,47 +0,0 @@
-{-# LANGUAGE TypeFamilies, FlexibleInstances #-}
-module Data.String.Interned.Internal
-  ( InternedString(..)
-  ) where
-
-import Data.String
-import Data.Interned
-import Data.Hashable
-import Data.Foldable
-import Data.Function (on)
-
-data InternedString = IS 
-  {-# UNPACK #-} !Id
-  String
-
-instance IsString InternedString where
-  fromString = intern
-
-instance Eq InternedString where
-  (==) = (==) `on` identity
-
-instance Ord InternedString where
-  compare = compare `on` identity
-
-instance Show InternedString where
-  showsPrec d (IS _ b) = showsPrec d b
-
-instance Interned InternedString where
-  type Uninterned InternedString = String
-  data Description InternedString = Cons {-# UNPACK #-} !Char String | Nil
-    deriving (Eq) 
-  describe (c:cs) = Cons c cs
-  describe []     = Nil
-  identify = IS
-  identity (IS i _) = i
-  cache = stringCache
-
-instance Uninternable InternedString where
-  unintern (IS _ b) = b 
-
-instance Hashable (Description InternedString) where
-  hash (Cons c s) = foldl' hashWithSalt (hashWithSalt 0 c) s
-  hash Nil        = 0
-
-stringCache :: Cache InternedString
-stringCache = mkCache
-{-# NOINLINE stringCache #-}
diff --git a/Data/Text/Interned.hs b/Data/Text/Interned.hs
deleted file mode 100644
--- a/Data/Text/Interned.hs
+++ /dev/null
@@ -1,5 +0,0 @@
-module Data.Text.Interned
-  ( InternedText
-  ) where
-
-import Data.Text.Interned.Internal
diff --git a/Data/Text/Interned/Internal.hs b/Data/Text/Interned/Internal.hs
deleted file mode 100644
--- a/Data/Text/Interned/Internal.hs
+++ /dev/null
@@ -1,44 +0,0 @@
-{-# LANGUAGE TypeFamilies, FlexibleInstances #-}
-module Data.Text.Interned.Internal
-  ( InternedText(..)
-  ) where
-
-import Data.String
-import Data.Interned
-import Data.Text
-import Data.Hashable
-import Data.Function (on)
-
-data InternedText = InternedText 
-  {-# UNPACK #-} !Id
-  {-# UNPACK #-} !Text
-
-instance IsString InternedText where
-  fromString = intern . pack
-
-instance Eq InternedText where
-  (==) = (==) `on` identity
-
-instance Ord InternedText where
-  compare = compare `on` identity
-
-instance Show InternedText where
-  showsPrec d (InternedText _ b) = showsPrec d b
-
-instance Interned InternedText where
-  type Uninterned InternedText = Text
-  data Description InternedText = DT {-# UNPACK #-} !Text deriving (Eq) 
-  describe = DT
-  identify = InternedText
-  identity (InternedText i _) = i
-  cache = itCache
-
-instance Uninternable InternedText where
-  unintern (InternedText _ b) = b 
-
-instance Hashable (Description InternedText) where
-  hash (DT h) = hash h
-
-itCache :: Cache InternedText
-itCache = mkCache
-{-# NOINLINE itCache #-}
diff --git a/intern.cabal b/intern.cabal
--- a/intern.cabal
+++ b/intern.cabal
@@ -1,6 +1,6 @@
 name:          intern
 category:      Data, Data Structures
-version:       0.4.0
+version:       0.5.0
 license:       BSD3
 cabal-version: >= 1.6
 license-file:  LICENSE
@@ -29,12 +29,12 @@
 
   exposed-modules:
     Data.Interned
+    Data.Interned.ByteString
+    Data.Interned.String
+    Data.Interned.Text
     Data.Interned.Internal
-    Data.ByteString.Interned
-    Data.ByteString.Interned.Internal
-    Data.String.Interned
-    Data.String.Interned.Internal
-    Data.Text.Interned
-    Data.Text.Interned.Internal
+    Data.Interned.Internal.ByteString
+    Data.Interned.Internal.String
+    Data.Interned.Internal.Text
 
   ghc-options: -Wall 
