diff --git a/Control/Concurrent/Speculation.hs b/Control/Concurrent/Speculation.hs
--- a/Control/Concurrent/Speculation.hs
+++ b/Control/Concurrent/Speculation.hs
@@ -15,14 +15,19 @@
     , specOnSTM'
     , specBySTM
     , specBySTM'
+    -- * Determining if a closure is evaluated
+    , unsafeGetTagBits
+    , unsafeIsEvaluated
     ) where
 
 import Control.Concurrent.STM
-import Control.Concurrent.Speculation.Internal (evaluated)
 import Control.Exception (Exception, throw, fromException)
 import Control.Parallel (par)
 import Data.Typeable (Typeable)
 import Data.Function (on)
+import Data.Bits ((.&.))
+import Foreign (sizeOf)
+import Unsafe.Coerce (unsafeCoerce)
 
 -- * Basic speculation
 
@@ -69,7 +74,7 @@
 -- | 'spec' with a user defined comparison function
 specBy :: (a -> a -> Bool) -> a -> (a -> b) -> a -> b
 specBy cmp g f a
-    | evaluated a = f a
+    | unsafeIsEvaluated a = f a
     | otherwise = specBy' cmp g f a
 {-# INLINE specBy #-}
 
@@ -140,7 +145,7 @@
 -- | 'specSTM' using a user defined comparison function
 specBySTM :: (a -> a -> Bool) -> STM a -> (a -> STM b) -> a -> STM b
 specBySTM cmp g f a 
-    | evaluated a = f a 
+    | unsafeIsEvaluated a = f a 
     | otherwise   = specBySTM' cmp g f a
 {-# INLINE specBySTM #-}
 
@@ -160,15 +165,28 @@
         _ -> throw e            -- this is a bigger problem
 {-# INLINE specBySTM' #-}
 
--- | 'specBySTM' . 'on' (==)'
+-- | @'specBySTM' . 'on' (==)@
 specOnSTM :: Eq c => (a -> c) -> STM a -> (a -> STM b) -> a -> STM b
 specOnSTM = specBySTM . on (==)
 {-# INLINE specOnSTM #-}
 
--- | 'specBySTM'' . 'on' (==)'
+-- | @'specBySTM'' . 'on' (==)@
 specOnSTM' :: Eq c => (a -> c) -> STM a -> (a -> STM b) -> a -> STM b
 specOnSTM' = specBySTM' . on (==)
 {-# INLINE specOnSTM' #-}
 
 data Speculation = Speculation deriving (Show,Eq,Typeable)
 instance Exception Speculation
+
+-- | Used to inspect tag bits
+data Box a = Box a
+
+-- | Inspect the dynamic pointer tagging bits of a closure. This is an impure function that relies on GHC internals and may falsely return 0, but never give the wrong tag number if it returns a non-0 value.
+unsafeGetTagBits :: a -> Int
+unsafeGetTagBits a = unsafeCoerce (Box a) .&. (sizeOf (undefined :: Int) - 1)
+{-# INLINE unsafeGetTagBits #-}
+
+-- | Returns a guess as to whether or not a value has been evaluated. This is an impure function that relies on GHC internals and will return false negatives, but no false positives. This is unsafe as the value of this function will vary (from False to True) over the course of otherwise pure invocations!
+unsafeIsEvaluated :: a -> Bool
+unsafeIsEvaluated a = unsafeGetTagBits a /= 0
+{-# INLINE unsafeIsEvaluated #-}
diff --git a/Control/Concurrent/Speculation/Internal.hs b/Control/Concurrent/Speculation/Internal.hs
deleted file mode 100644
--- a/Control/Concurrent/Speculation/Internal.hs
+++ /dev/null
@@ -1,57 +0,0 @@
-{-# LANGUAGE Rank2Types #-}
-module Control.Concurrent.Speculation.Internal 
-    ( 
-    -- * Determining if a closure is evaluated
-      evaluated
-    -- * Codensity monad
-    , Codensity(..)
-    , liftCodensity
-    , lowerCodensity
---  , returning
-    ) where
-
-import Control.Applicative
-import Control.Monad
-
-import Data.Bits ((.&.))
-import Foreign (sizeOf)
-import Unsafe.Coerce (unsafeCoerce)
-
-
--- | Used to inspect tag bits
-data Box a = Box a
-
--- | Inspect the dynamic pointer tagging bits of a closure. This is an impure function that
--- relies on GHC internals and will falsely return 0, but (hopefully) never give the wrong tag number if it returns a non-0 value.
-tag :: a -> Int
-tag a = unsafeCoerce (Box a) .&. (sizeOf (undefined :: Int) - 1)
-{-# INLINE tag #-}
-
--- | Returns a guess as to whether or not a value has been evaluated. This is an impure function
--- that relies on GHC internals and will return false negatives, but (hopefully) no false positives. This is unsafe as the value of this function will vary (from False to True) over the course of pure invocations!
-evaluated :: a -> Bool
-evaluated a = tag a /= 0
-{-# INLINE evaluated #-}
-
--- returning :: Monad m => (a -> a -> b) -> a -> a -> m b
--- returning f a b = return (f a b)
--- {-# INLINE returning #-}
-
-newtype Codensity f a = Codensity { runCodensity :: forall r. (a -> f r) -> f r } 
-
-instance Functor (Codensity f) where
-    fmap f (Codensity m) = Codensity $ \k -> m (k . f)
-
-instance Applicative (Codensity f) where
-    pure = return
-    (<*>) = ap
-
-instance Monad (Codensity f) where
-    return x = Codensity (\k -> k x)
-    Codensity m >>= f = Codensity (\k -> m (\a -> runCodensity (f a) k))
-
-liftCodensity :: Monad m => m a -> Codensity m a 
-liftCodensity m = Codensity (m >>=)
-
-lowerCodensity :: Monad m => Codensity m a -> m a
-lowerCodensity a = runCodensity a return
diff --git a/speculation.cabal b/speculation.cabal
--- a/speculation.cabal
+++ b/speculation.cabal
@@ -1,5 +1,5 @@
 name:           speculation
-version:        0.5.0
+version:        0.5.1
 license:        BSD3
 license-file:   LICENSE
 author:         Edward A. Kmett
@@ -17,7 +17,7 @@
  .
  For example:
  . 
- @'spec' g f a@ evaluates @f g@ while forcing @a@, if @g == a@ then @f g@ is returned, otherwise @f a@ is evaluated and returned. Furthermore, if the argument has already been evaluated, we skip the @f g@ computation entirely. If a good guess at the value of @a@ is available, this is one way to induce parallelism in an otherwise sequential task. However, if the guess isn\'t available more cheaply than the actual answer, then this saves no work and if the guess is wrong, you risk evaluating the function twice.
+ @'spec' g f a@ evaluates @f g@ while forcing @a@, if @g == a@ then @f g@ is returned, otherwise @f a@ is evaluated and returned. Furthermore, if the argument has already been evaluated, we skip the @f g@ computation entirely. If a good guess at the value of @a@ is available, this is one way to induce parallelism in an otherwise sequential task. However, if the guess isn\'t available more cheaply than the actual answer, then this saves no work and if the guess is wrong, you risk evaluating the function twice. 
  .
  The best-case timeline looks like:
  .
@@ -39,9 +39,9 @@
  .
  'specSTM' provides a similar time table for STM actions, but also rolls back side-effects.
  . 
- /Changes in 0.5.0:/
+ /Changes in 0.5.1:/
  . 
- * Added monadic and transactional folds to Data.Foldable.Speculation. 
+ * Exposed unsafeGetTagBits and unsafeIsEvaluated
 
 copyright:          (c) 2010 Edward A. Kmett
 build-type:         Simple
@@ -60,6 +60,3 @@
   exposed-modules:
     Control.Concurrent.Speculation
     Data.Foldable.Speculation
-
-  other-modules:
-    Control.Concurrent.Speculation.Internal
