diff --git a/Control/Concurrent/STM/Speculation.hs b/Control/Concurrent/STM/Speculation.hs
new file mode 100644
--- /dev/null
+++ b/Control/Concurrent/STM/Speculation.hs
@@ -0,0 +1,74 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+module Control.Concurrent.STM.Speculation 
+    ( specSTM
+    , specSTM'
+    ) where
+
+import Control.Concurrent.STM
+import Control.Concurrent.Speculation (evaluated)
+import Control.Exception (Exception, throw, fromException)
+import Control.Parallel (par)
+import Data.Typeable (Typeable)
+import System.IO.Unsafe (unsafePerformIO)
+
+newtype Speculation = Speculation Int deriving (Show,Eq,Typeable)
+instance Exception Speculation
+
+-- | @'specSTM' g f a@ evaluates @f g@ while forcing @a@, if @g == a@ then @f g@ is returned. Otherwise the side-effects 
+-- of the current STM transaction are rolled back and @f a@ is evaluated.
+--   
+-- If the argument @a@ is already evaluated, we don\'t bother to perform @f g@ at all.
+--
+-- 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.
+--
+-- > specSTM a f a = f $! a
+--
+-- The best-case timeline looks like:
+--
+-- > [------ f g ------]
+-- >     [------- a -------]
+-- > [--- specSTM g f a ---]
+--
+-- The worst-case timeline looks like:
+--
+-- > [------ f g ------] 
+-- >     [------- a -------]
+-- >                       [-- rollback --]
+-- >                                      [------ f a ------]     
+-- > [------------------ spec g f a ------------------------]
+--
+-- Compare these to the timeline of @f $! a@:
+--
+-- > [------- a -------]
+-- >                   [------ f a ------]
+
+specSTM :: Eq a => a -> (a -> STM b) -> a -> STM b
+specSTM g f a 
+    | evaluated a = f a 
+    | otherwise   = specSTM' g f a
+
+-- | Unlike @specSTM@, @specSTM'@ doesn't check if the argument has already been evaluated.
+
+specSTM' :: Eq a => a -> (a -> STM b) -> a -> STM b
+specSTM' g f a = a `par` do
+    exn <- freshSpeculation
+    let try = do
+            result <- f g 
+            if a /= g 
+                then throw exn
+                else return result
+    try `catchSTM` \e -> case fromException e of
+        Just exn' | exn == exn' -> f a -- rerun with alternative inputs
+        _ -> throw e                   -- this is somebody else's problem
+
+speculationSupply :: TVar Int
+speculationSupply = unsafePerformIO $ newTVarIO 0
+
+freshSpeculation :: STM Speculation
+freshSpeculation = do
+    n <- readTVar speculationSupply
+    writeTVar speculationSupply $! n + 1
+    return (Speculation n)
diff --git a/Control/Concurrent/Speculation.hs b/Control/Concurrent/Speculation.hs
--- a/Control/Concurrent/Speculation.hs
+++ b/Control/Concurrent/Speculation.hs
@@ -5,8 +5,6 @@
     , evaluated
     , specFoldr
     , specFoldl
---    , specFoldl'
---    , specFoldr'
     , Speculative(..)
     , WrappedFoldable(..)
     , WithoutSpeculation(..)
@@ -52,7 +50,7 @@
 -- 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 a f a = a `seq` f a
+-- > spec a f a = f $! a
 --
 -- The best-case timeline looks like:
 --
@@ -67,7 +65,7 @@
 -- >                  [---- f a ----]
 -- > [------- spec g f a -----------]
 --
--- Compared to the unspeculated timeline of
+-- Compare these to the timeline of @f $! a@:
 --
 -- > [---- a -----]
 -- >              [---- f a ----]
@@ -76,17 +74,11 @@
 spec g f a 
     | evaluated a = f a 
     | otherwise = spec' g f a
+{-# INLINE spec #-}
 
--- | @'spec'' g f a@ evaluates a function @f @ using a cheap guess @g@ at the argument in parallel with forcing the argument.
---
--- This is one way to induce parallelism in an otherwise sequential task. 
--- Unlike `spec` this version
--- does not check to see if the argument has already been evaluated before evaluating the speculated
--- version. This is useful when you know 'evaluated' will always return False.
---
--- The following identity holds:
---
--- > spec' a f a = a `seq` f a
+-- | Unlike 'spec', this version does not check to see if the argument has already been evaluated. This can save
+-- a small amount of work when you know the argument will always require computation.
+
 spec' :: Eq a => a -> (a -> b) -> a -> b
 spec' guess f a = 
     speculation `par` 
@@ -95,25 +87,49 @@
         else f a
     where 
         speculation = f guess
-{-# INLINE spec #-}
+{-# INLINE spec' #-}
 
--- | Compute a right biased fold. The estimator function provides a guess at the value of the suffix
+-- | Given a valid estimator @g@, @'specFoldr' g f z xs@ yields the same answer as @'foldr'' f z xs@.
+--
+-- @g n@ should supply an estimate of the value returned from folding over the last @n@ elements of the container.
+--
+-- If @g n@ is accurate a reasonable percentage of the time and faster to compute than the fold, then this can
+-- provide increased opportunities for parallelism.
+--
+-- > specFoldr = specFoldrN 0
+
 specFoldr :: (Speculative f, Eq b) => (Int -> b) -> (a -> b -> b) -> b -> f a -> b
 specFoldr = specFoldrN 0
 {-# INLINE specFoldr #-}
 
--- | Compute a left-biased fold. The estimator function provides a guess at the value of the prefix
+-- | Given a valid estimator @g@, @'specFoldl' g f z xs@ yields the same answer as @'foldl'' f z xs@.
+--
+-- @g n@ should supply an estimate of the value returned from folding over the first @n@ elements of the container.
+--
+-- If @g n@ is accurate a reasonable percentage of the time and faster to compute than the fold, then this can
+-- provide increased opportunities for parallelism.
+--
+-- > specFoldl = specFoldlN 0
+
 specFoldl  :: (Speculative f, Eq b) => (Int -> b) -> (b -> a -> b) -> b -> f a -> b
 specFoldl = specFoldlN 0
 {-# INLINE specFoldl #-}
 
 class Foldable f => Speculative f where
-    -- | Compute a right-biased fold. The estimator function is a guess at the value of the prefix
+    -- | 'specFoldr1' is to 'foldr1'' as 'specFoldr' is to 'foldr''
     specFoldr1 :: Eq a => (Int -> a) -> (a -> a -> a) -> f a -> a
+
+    -- | Given a valid estimator @g@, @'specFoldrN' n g f z xs@ yields the same answer as @'foldr' f z xs@.
+    -- 
+    -- @g m@ should supply an estimate of the value returned from folding over the last @m - n@ elements of the container.
     specFoldrN :: Eq b => Int -> (Int -> b) -> (a -> b -> b) -> b -> f a -> b
 
-    -- | Compute a left biased fold. the estimator function is a guess at the value of the prefix
+    -- | 'specFoldl1' is to 'foldl1'' as 'specFoldl' is to 'foldl''
     specFoldl1 :: Eq a => (Int -> a) -> (a -> a -> a) -> f a -> a
+
+    -- | Given a valid estimator @g@, @'specFoldlN' n g f z xs@ yields the same answer as @'foldl' f z xs@.
+    -- 
+    -- @g m@ should supply an estimate of the value returned from folding over the first @m - n@ elements of the container.
     specFoldlN :: Eq b => Int -> (Int -> b) -> (b -> a -> b) -> b -> f a -> b
 
     specFoldr1 g f = specFoldr1 g f . toList
@@ -159,16 +175,7 @@
 instance Speculative IntMap
 instance Speculative Seq
 
--- specFoldl' :: (Speculative f, Eq a) => (Int -> b) -> (b -> a -> b) -> b -> f a -> b
--- specFoldl' g f z0 xs = specFoldr g' f' id xs z0 where
---     f' x k z = k $! f z x
---    g' = undefined -- n z = f (g n) z
-
--- specFoldr' :: (Speculative f, Eq a) => (Int -> b) -> (a -> b -> b) -> b -> f a -> b
--- specFoldr' g f z0 xs = specFoldl g' f' id xs z0 where
---    f' x k z = k $! f x z
---    g' = undefined -- n z = f (g n) z
-
+-- | Transform an arbitrary 'Foldable' into a 'Speculative' container
 newtype WrappedFoldable f a = WrappedFoldable { getWrappedFoldable :: f a } 
     deriving (Functor, Foldable, Traversable)
 
@@ -200,6 +207,7 @@
     dataTypeOf _ = wrappedDataType
     dataCast1 f = gcast1 f
 
+-- | Provides a 'Speculative' container that doesn't actually speculate.
 newtype WithoutSpeculation f a = WithoutSpeculation { getWithoutSpeculation :: f a } 
     deriving (Functor, Foldable, Traversable)
 
diff --git a/speculation.cabal b/speculation.cabal
--- a/speculation.cabal
+++ b/speculation.cabal
@@ -1,5 +1,5 @@
 name:           speculation
-version:        0.0.2
+version:        0.1.0
 license:        BSD3
 license-file:   LICENSE
 author:         Edward A. Kmett
@@ -8,20 +8,20 @@
 homepage:       http://github.com/ekmett/speculation
 category:       Concurrency
 synopsis:       A framework for safe, programmable, speculative parallelism
-description:    
+description:
     A framework for safe, programmable, speculative parallelism, loosely based on
     <http://research.microsoft.com/pubs/118795/pldi026-vaswani.pdf>
-    . 
+    .
     @'spec' g f a@ evaluates @f g@ while forcing @a@, if @g == a@ then @f g@ is returned. Otherwise @f a@ is evaluated.
-    .   
+    .
     Furthermore, if the argument has already been evaluated, we avoid sparking the parallel computation at all.
     .
-    If a good guess at the value of @a@ is available, this is one way to induce parallelism in an otherwise sequential task. 
+    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 a f a = a `seq` f a
+    > spec a f a = f $! a
     .
     The best-case timeline looks like:
     .
@@ -36,18 +36,24 @@
     >                  [---- f a ----]
     > [------- spec g f a -----------]
     .
-    Compared to the unspeculated timeline of
+    Compare these to the timeline of @f $! a@:
     .
     > [---- a -----]
     >              [---- f a ----]
     .
-    Changes since 0.0.1
+    'specSTM' provides a similar time table for STM actions, but also rolls back side-effects.
     .
+    /Changes in 0.1.0:/
+    .
+    * Added @Control.Concurrent.STM.Speculation@ with 'specSTM', and 'specSTM''
+    .
+    /Changes in 0.0.2:/
+    .
     * 'specFoldr1' bug fix
     .
     * Added 'spec'' combinator
     .
-    Changes since 0.0.0
+    /Changes in 0.0.1:/
     .
     * Added 'WithoutSpeculation' and 'WrappedFoldable'
 
@@ -61,10 +67,12 @@
   ghc-options: -Wall
 
   build-depends:
-    base >= 4 && < 6, 
+    base >= 4 && < 6,
     containers >= 0.2.0.1,
     array >= 0.2 && < 0.4,
-    parallel >= 2.2 && < 2.3
+    parallel >= 2.2 && < 2.3,
+    stm >= 2.1 && < 2.2
 
   exposed-modules:
     Control.Concurrent.Speculation
+    Control.Concurrent.STM.Speculation
