diff --git a/Control/Exception/Control.hs b/Control/Exception/Control.hs
--- a/Control/Exception/Control.hs
+++ b/Control/Exception/Control.hs
@@ -47,8 +47,10 @@
 #else
     , block, unblock
 #endif
-    , blocked
 
+#if !MIN_VERSION_base(4,4,0)
+    , blocked
+#endif
       -- * Brackets
     , bracket, bracket_, bracketOnError
 
@@ -65,7 +67,6 @@
 import Data.Function   ( ($) )
 import Data.Either     ( Either(Left, Right), either )
 import Data.Maybe      ( Maybe )
-import Data.Bool       ( Bool )
 import Control.Monad   ( Monad, (>>=), return, liftM )
 import System.IO.Error ( IOError )
 
@@ -96,12 +97,18 @@
 #else
     , block, unblock
 #endif
+#if !MIN_VERSION_base(4,4,0)
     , blocked
+#endif
     , bracket, bracket_, bracketOnError
     , finally, onException
     )
 import qualified Control.Exception as E
 
+#if !MIN_VERSION_base(4,4,0)
+import Data.Bool ( Bool )
+#endif
+
 -- from monad-control (this package):
 import Control.Monad.IO.Control ( MonadControlIO
                                 , controlIO
@@ -256,11 +263,13 @@
 unblock = liftIOOp_ E.unblock
 #endif
 
+#if !MIN_VERSION_base(4,4,0)
 -- | Generalized version of 'E.blocked'.
 -- returns @True@ if asynchronous exceptions are blocked in the
 -- current thread.
 blocked ∷ MonadIO m ⇒ m Bool
 blocked = liftIO E.blocked
+#endif
 
 
 --------------------------------------------------------------------------------
diff --git a/NEWS b/NEWS
new file mode 100644
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,323 @@
+0.2.0.1
+
+(Released on: Wed Mar 16 15:53:50 UTC 2011)
+
+* Added laws for MonadTransControl and MonadControlIO
+
+* Bug fix: Add proper laziness to the MonadTransControl instances
+  of the lazy StateT, WriteT and RWST
+  These all failed the law: control $ \run -> run t = t
+  where t = return undefined
+
+* Add INLINABLE pragmas for most public functions
+  A simple benchmark showed some functions
+  (bracket and mask) improving by 30%.
+
+
+0.2
+
+(Released on: Wed Feb 9 12:05:26 UTC 2011)
+
+* Use RunInBase in the type of idLiftControl.
+
+* Added this NEWS file.
+
+* Only parameterize Run with t and use RankNTypes to quantify n and o
+  -liftControl :: (Monad m, Monad n, Monad o) => (Run t n o -> m a) -> t m a
+  +liftControl :: Monad m => (Run t -> m a) -> t m a
+
+  -type Run t n o = forall b. t n b -> n (t o b)
+  +type Run t = forall n o b. (Monad n, Monad o, Monad (t o)) => t n b -> n (t o b)
+
+  Bumped version from 0.1 to 0.2 to indicate this breaking change in API.
+
+* Added example of a derivation of liftControlIO.
+  Really enlightening!
+
+
+0.1
+
+(Released on: Sat Feb 5 23:36:21 UTC 2011)
+
+* Initial release
+
+This is the announcement message sent to the Haskell mailinglists:
+http://www.mail-archive.com/haskell@haskell.org/msg23278.html
+
+
+Dear all,
+
+Several attempts have been made to lift control operations (functions
+that use monadic actions as input instead of just output) through
+monad transformers:
+
+MonadCatchIO-transformers[1] provided a type class that allowed to
+overload some often used control operations (catch, block and
+unblock). Unfortunately that library was limited to those operations.
+It was not possible to use, say, alloca in a monad transformer. More
+importantly however, the library was broken as was explained[2] by
+Michael Snoyman. In response Michael created the MonadInvertIO type
+class which solved the problems. Then Anders Kaseorg created the
+monad-peel library which provided an even nicer implementation.
+
+monad-control is a rewrite of monad-peel that uses CPS style
+operations and exploits the RankNTypes language extension to simplify
+and speedup most functions. A very preliminary and not yet fully
+representative, benchmark shows that monad-control is on average about
+2.6 times faster than monad-peel:
+
+bracket:  2.4 x faster
+bracket_: 3.1 x faster
+catch:    1.8 x faster
+try:      4.0 x faster
+mask:     2.0 x faster
+
+Note that, although the package comes with a test suite that passes, I
+still consider it highly experimental.
+
+
+API DOCS:
+
+http://hackage.haskell.org/package/monad-control
+
+
+INSTALLING:
+
+$ cabal update
+$ cabal install monad-control
+
+
+TESTING:
+
+The package contains a copy of the monad-peel test suite written by
+Anders. You can perform the tests using:
+
+$ cabal unpack monad-control
+$ cd monad-control
+$ cabal configure -ftest
+$ cabal test
+
+
+BENCHMARKING:
+
+$ darcs get http://bifunctor.homelinux.net/~bas/bench-monad-peel-control/
+$ cd bench-monad-peel-control
+$ cabal configure
+$ cabal build
+$ dist/build/bench-monad-peel-control/bench-monad-peel-control
+
+
+DEVELOPING:
+
+The darcs repository will be hosted on code.haskell.org ones that
+server is back online. For the time being you can get the repository
+from:
+
+$ darcs get http://bifunctor.homelinux.net/~bas/monad-control/
+
+
+TUTORIAL:
+
+This short unpolished tutorial will explain how to lift control
+operations through monad transformers. Our goal is to lift a control
+operation like:
+
+foo ∷ M a → M a
+
+where M is some monad, into a transformed monad like 'StateT M':
+
+foo' ∷ StateT M a → StateT M a
+
+The first thing we need to do is write an instance for the
+MonadTransControl type class:
+
+class MonadTrans t ⇒ MonadTransControl t where
+  liftControl ∷ (Monad m, Monad n, Monad o)
+              ⇒ (Run t n o → m a) → t m a
+
+If you ignore the Run argument for now, you'll see that liftControl is
+identical to the 'lift' method of the MonadTrans type class:
+
+class MonadTrans t where
+    lift ∷ Monad m ⇒ m a → t m a
+
+So the instance for MonadTransControl will probably look very much
+like the instance for MonadTrans. Let's see:
+
+instance MonadTransControl (StateT s) where
+    liftControl f = StateT $ \s → liftM (\x → (x, s)) (f run)
+
+So what is this run function? Let's look at its type:
+
+type Run t n o = ∀ b. t n b → n (t o b)
+
+The run function executes a transformed monadic action 't n b' in the
+non-transformed monad 'n'. In our case the 't' will be a StateT
+computation. The only way to run a StateT computation is to give it
+some state and the only state we have lying around is the one from the
+outer computation: 's'. So let's run it on 's':
+
+instance MonadTransControl (StateT s) where
+    liftControl f =
+        StateT $ \s →
+          let run t = ... runStateT t s ...
+          in liftM (\x → (x, s)) (f run)
+
+Now that we are able to run a transformed monadic action, we're almost
+done. Look at the type of Run again. The function should leave the
+result 't o b' in the monad 'n'. This 't o b' computation should
+contain the final state after running the supplied 't n b'
+computation. In case of our StateT it should contain the final state
+s':
+
+instance MonadTransControl (StateT s) where
+    liftControl f =
+        StateT $ \s →
+          let run t = liftM (\(x, s') → StateT $ \_ → return (x, s'))
+                            (runStateT t s)
+          in liftM (\x → (x, s)) (f run)
+
+This final computation, "StateT $ \_ → return (x, s')", can later be
+used to restore the final state. Now that we have our
+MonadTransControl instance we can start using it. Recall that our goal
+was to lift "foo ∷ M a → M a" into our StateT transformer yielding the
+function "foo' ∷ StateT M a → StateT M a".
+
+To define foo', the first thing we need to do is call liftControl:
+
+foo' t = liftControl $ \run → ...
+
+This captures the current state of the StateT computation and provides
+us with the run function that allows us to run a StateT computation on
+this captured state.
+
+Now recall the type of liftControl ∷ (Run t n o → m a) → t m a. You
+can see that in place of the ... we must fill in a value of type 'm
+a'. In our case this will be a value of type 'M a'. We can construct
+such a value by calling foo. However, foo expects an argument of type
+'M a'. Fortunately we can provide one if we convert the supplied 't'
+computation of type 'StateT M a' to 'M a' using our run function of
+type ∀ b. StateT M b → M (StateT o b):
+
+foo' t = ... liftControl $ \run → foo $ run t
+
+However, note that the run function returns the final StateT
+computation inside M. So the type of the right hand side is now
+'StateT M (StateT o b)'. We would like to restore this final state. We
+can do that using join:
+
+foo' t = join $ liftControl $ \run → foo $ run t
+
+That's it! Note that because it's so common to join after a
+liftControl I provide an abstraction for it:
+
+control = join ∘ liftControl
+
+Allowing you to simplify foo' to:
+
+foo' t = control $ \run → foo $ run t
+
+Probably the most common control operations that you want to lift
+through your transformers are IO operations. Think about: bracket,
+alloca, mask, etc.. For this reason I provide the MonadControlIO type
+class:
+
+class MonadIO m ⇒ MonadControlIO m where
+  liftControlIO ∷ (RunInBase m IO → IO a) → m a
+
+Again, if you ignore the RunInBase argument, you will see that
+liftControlIO is identical to the liftIO method of the MonadIO type
+class:
+
+class Monad m ⇒ MonadIO m where
+    liftIO ∷ IO a → m a
+
+Just like Run, RunInBase allows you to run your monadic computation
+inside your base monad, which in case of liftControlIO is IO:
+
+type RunInBase m base = ∀ b. m b → base (m b)
+
+The instance for the base monad is trivial:
+
+instance MonadControlIO IO where
+    liftControlIO = idLiftControl
+
+idLiftControl directly executes f and passes it a run function which
+executes the given action and lifts the result r into the trivial
+'return r' action:
+
+idLiftControl ∷ Monad m ⇒ ((∀ b. m b → m (m b)) → m a) → m a
+idLiftControl f = f $ liftM $ \r -> return r
+
+The instances for the transformers are all identical. Let's look at
+StateT and ReaderT:
+
+instance MonadControlIO m ⇒ MonadControlIO (StateT s m) where
+    liftControlIO = liftLiftControlBase liftControlIO
+
+instance MonadControlIO m ⇒ MonadControlIO (ReaderT r m) where
+    liftControlIO = liftLiftControlBase liftControlIO
+
+The magic function is liftLiftControlBase. This function is used to
+compose two liftControl operations, the outer provided by a
+MonadTransControl instance and the inner provided as the argument:
+
+liftLiftControlBase ∷ (MonadTransControl t, Monad base, Monad m, Monad (t m))
+                    ⇒ ((RunInBase m     base → base a) →   m a)
+                    → ((RunInBase (t m) base → base a) → t m a)
+liftLiftControlBase lftCtrlBase =
+  \f → liftControl $ \run →
+         lftCtrlBase $ \runInBase →
+           f $ liftM (join ∘ lift) ∘ runInBase ∘ run
+
+Basically it captures the state of the outer monad transformer using
+liftControl. Then it captures the state of the inner monad using the
+supplied lftCtrlBase function. If you recall the identical definitions
+of the liftControlIO methods: 'liftLiftControlBase liftControlIO' you
+will see that this lftCtrlBase function is the recursive step of
+liftLiftControlBase. If you use 'liftLiftControlBase liftControlIO' in
+a stack of monad transformers a chain of liftControl operations is
+created:
+
+liftControl $ \run1 -> liftControl $ \run2 -> liftControl $ \run3 -> ...
+
+This will recurse until we hit the base monad. Then
+liftLiftControlBase will finally run f in the base monad supplying it
+with a run function that is able to run a 't m a' computation in the
+base monad. It does this by composing the run and runInBase functions.
+Note that runInBase is basically the composition: '... ∘ run3 ∘ run2'.
+
+However, just composing the run and runInBase functions is not enough.
+Namely: runInBase ∘ run ∷ ∀ b. t m b → base (m (t m b)) while we need
+to have ∀ b. t m b → base (t m b). So we need to lift the 'm (t m b)'
+computation inside t yielding: 't m (t m b)' and then join that to get
+'t m b'.
+
+Now that we have our MonadControlIO instances we can start using them.
+Let's look at how to lift 'bracket' into a monad supporting
+MonadControlIO. Before we do that I define a little convenience
+function similar to 'control':
+
+controlIO = join ∘ liftControlIO
+
+Bracket just calls controlIO which captures the state of m and
+provides us with a runInIO function which allows us to run an m
+computation in IO:
+
+bracket ∷ MonadControlIO m
+        ⇒ m a → (a → m b) → (a → m c) → m c
+bracket before after thing =
+  controlIO $ \runInIO →
+    E.bracket (runInIO before)
+              (\m → runInIO $ m >>= after)
+              (\m → runInIO $ m >>= thing)
+
+I welcome any comments, questions or patches.
+
+Regards,
+
+Bas
+
+[1] http://hackage.haskell.org/package/MonadCatchIO-transformers
+[2] http://docs.yesodweb.com/blog/invertible-monads-exceptions-allocations/
+[3] http://hackage.haskell.org/package/monad-peel
diff --git a/README.markdown b/README.markdown
new file mode 100644
--- /dev/null
+++ b/README.markdown
@@ -0,0 +1,19 @@
+This package defines the type class `MonadControlIO`, a subset of
+`MonadIO` into which generic control operations such as `catch` can be
+lifted from `IO`.  Instances are based on monad transformers in
+`MonadTransControl`, which includes all standard monad transformers in
+the `transformers` library except `ContT`.  For convenience, it
+provides a wrapped version of `Control.Exception` with types
+generalized from `IO` to all monads in `MonadControlIO`.
+
+Note that this package is a rewrite of Anders Kaseorg's `monad-peel`
+library.  The main difference is that this package provides CPS style
+operators and exploits the `RankNTypes` language extension to simplify
+most definitions.
+
+The package includes a copy of the `monad-peel` testsuite written by
+Anders Kaseorg The tests can be performed by using `cabal test`.
+
+[This `critertion`](https://github.com/basvandijk/bench-monad-peel-control)
+based benchmark shows that `monad-control` is on average about 2.5
+times faster than `monad-peel`.
diff --git a/Setup.hs b/Setup.hs
--- a/Setup.hs
+++ b/Setup.hs
@@ -10,17 +10,12 @@
 -------------------------------------------------------------------------------
 
 -- from base
-import Control.Monad       ( (>>), return )
-import Data.Bool           ( Bool )
-import System.Cmd          ( system )
-import System.FilePath     ( (</>) )
-import System.IO           ( IO )
+import System.IO ( IO )
 
 -- from cabal
 import Distribution.Simple ( defaultMainWithHooks
                            , simpleUserHooks
-                           , UserHooks(runTests, haddockHook)
-                           , Args
+                           , UserHooks(haddockHook)
                            )
 
 import Distribution.Simple.LocalBuildInfo ( LocalBuildInfo(..) )
@@ -30,26 +25,13 @@
 
 
 -------------------------------------------------------------------------------
--- Cabal setup program with support for 'cabal test' and
--- which sets the CPP define '__HADDOCK __' when haddock is run.
+-- Cabal setup program which sets the CPP define '__HADDOCK __' when haddock is run.
 -------------------------------------------------------------------------------
 
 main ∷ IO ()
 main = defaultMainWithHooks hooks
   where
-    hooks = simpleUserHooks
-            { runTests    = runTests'
-            , haddockHook = haddockHook'
-            }
-
--- Run a 'test' binary that gets built when configured with '-ftest'.
-runTests' ∷ Args → Bool → PackageDescription → LocalBuildInfo → IO ()
-runTests' _ _ _ _ = system testcmd >> return ()
-  where testcmd = "."
-                  </> "dist"
-                  </> "build"
-                  </> "test-monad-control"
-                  </> "test-monad-control"
+    hooks = simpleUserHooks { haddockHook = haddockHook' }
 
 -- Define __HADDOCK__ for CPP when running haddock.
 haddockHook' ∷ PackageDescription → LocalBuildInfo → UserHooks → HaddockFlags → IO ()
diff --git a/monad-control.cabal b/monad-control.cabal
--- a/monad-control.cabal
+++ b/monad-control.cabal
@@ -1,5 +1,5 @@
 Name:                monad-control
-Version:             0.2.0.1
+Version:             0.2.0.2
 Synopsis:            Lift control operations, like exception catching, through monad transformers
 Description:
   This package defines the type class @MonadControlIO@, a subset of
@@ -21,32 +21,26 @@
   The following @critertion@ based benchmark shows that @monad-control@
   is on average about 2.5 times faster than @monad-peel@:
   .
-  <http://code.haskell.org/~basvandijk/code/bench-monad-peel-control>
+  <https://github.com/basvandijk/bench-monad-peel-control>
 
 License:             BSD3
 License-file:        LICENSE
 Author:              Bas van Dijk, Anders Kaseorg
 Maintainer:          Bas van Dijk <v.dijk.bas@gmail.com>
 Copyright:           (c) 2011 Bas van Dijk, Anders Kaseorg
+Homepage:            https://github.com/basvandijk/monad-control/
+Bug-reports:         https://github.com/basvandijk/monad-control/issues
 Category:            Control
 Build-type:          Custom
-Cabal-version:       >= 1.6
-
---------------------------------------------------------------------------------
+Cabal-version:       >= 1.9.2
 
-source-repository head
-  type:     darcs
-  location: http://code.haskell.org/~basvandijk/code/monad-control
+extra-source-files:  README.markdown, NEWS
 
 --------------------------------------------------------------------------------
 
-flag test
-  description: Build the testing suite
-  default:     False
-
-flag hpc
-  description: Enable program coverage on test executable
-  default:     False
+source-repository head
+  type:     git
+  location: git://github.com/basvandijk/monad-control.git
 
 --------------------------------------------------------------------------------
 
@@ -55,7 +49,7 @@
                    Control.Monad.IO.Control
                    Control.Exception.Control
 
-  Build-depends: base                 >= 3     && < 4.4
+  Build-depends: base                 >= 3     && < 4.5
                , base-unicode-symbols >= 0.1.1 && < 0.3
                , transformers         >= 0.2   && < 0.3
 
@@ -63,22 +57,17 @@
 
 --------------------------------------------------------------------------------
 
-executable test-monad-control
+test-suite test-threads
+  type:    exitcode-stdio-1.0
   main-is: test.hs
 
   ghc-options: -Wall
 
-  if flag(test)
-    build-depends: base                 >= 3     && < 4.4
-                 , base-unicode-symbols >= 0.1.1 && < 0.3
-                 , HUnit                >= 1.2.2 && < 1.3
-                 , test-framework       >= 0.2.4 && < 0.4
-                 , test-framework-hunit >= 0.2.4 && < 0.3
-    buildable: True
-  else
-    buildable: False
-
-  if flag(hpc)
-    ghc-options: -fhpc
+  build-depends: base                 >= 3     && < 4.5
+               , base-unicode-symbols >= 0.1.1 && < 0.3
+               , transformers         >= 0.2   && < 0.3
+               , HUnit                >= 1.2.2 && < 1.3
+               , test-framework       >= 0.2.4 && < 0.5
+               , test-framework-hunit >= 0.2.4 && < 0.3
 
 --------------------------------------------------------------------------------
diff --git a/test.hs b/test.hs
deleted file mode 100644
--- a/test.hs
+++ /dev/null
@@ -1,159 +0,0 @@
-{-# LANGUAGE DeriveDataTypeable #-}
-
--- from base:
-import Prelude hiding (catch)
-import Data.IORef
-import Data.Maybe
-import Data.Typeable (Typeable)
-
--- from transformers:
-import Control.Monad.IO.Class (liftIO)
-
-import Control.Monad.Trans.Identity
-import Control.Monad.Trans.List
-import Control.Monad.Trans.Maybe
-import Control.Monad.Trans.Reader
-import Control.Monad.Trans.Writer
-import Control.Monad.Trans.Error
-import Control.Monad.Trans.State
-import qualified Control.Monad.Trans.RWS as RWS
-
--- from monad-control (this package):
-import Control.Exception.Control
-import Control.Monad.IO.Control (MonadControlIO)
-
--- from test-framework:
-import Test.Framework (defaultMain, testGroup, Test)
-
- -- from test-framework-hunit:
-import Test.Framework.Providers.HUnit
-
--- from hunit:
-import Test.HUnit hiding (Test)
-
-
-main :: IO ()
-main = defaultMain
-    [ testSuite "IdentityT" runIdentityT
-    , testSuite "ListT" $ fmap head . runListT
-    , testSuite "MaybeT" $ fmap fromJust . runMaybeT
-    , testSuite "ReaderT" $ flip runReaderT "reader state"
-    , testSuite "WriterT" runWriterT'
-    , testSuite "ErrorT" runErrorT'
-    , testSuite "StateT" $ flip evalStateT "state state"
-    , testSuite "RWST" $ \m -> runRWST' m "RWS in" "RWS state"
-    , testCase "ErrorT throwError" case_throwError
-    , testCase "WriterT tell" case_tell
-    ]
-  where
-    runWriterT' :: Functor m => WriterT [Int] m a -> m a
-    runWriterT' = fmap fst . runWriterT
-    runErrorT' :: Functor m => ErrorT String m () -> m ()
-    runErrorT' = fmap (either (const ()) id) . runErrorT
-    runRWST' :: (Monad m, Functor m) => RWS.RWST r [Int] s m a -> r -> s -> m a
-    runRWST' m r s = fmap fst $ RWS.evalRWST m r s
-
-testSuite :: MonadControlIO m => String -> (m () -> IO ()) -> Test
-testSuite s run = testGroup s
-    [ testCase "finally" $ case_finally run
-    , testCase "catch" $ case_catch run
-    , testCase "bracket" $ case_bracket run
-    , testCase "bracket_" $ case_bracket_ run
-    , testCase "onException" $ case_onException run
-    ]
-
-ignore :: IO () -> IO ()
-ignore x =
-    catch x go
-  where
-    go :: SomeException -> IO ()
-    go _ = return ()
-
-data Exc = Exc
-    deriving (Show, Typeable)
-instance Exception Exc
-
-one :: Int
-one = 1
-
-case_finally :: MonadControlIO m => (m () -> IO ()) -> Assertion
-case_finally run = do
-    i <- newIORef one
-    ignore
-        (run $ (do
-            liftIO $ writeIORef i 2
-            error "error") `finally` (liftIO $ writeIORef i 3))
-    j <- readIORef i
-    j @?= 3
-
-case_catch :: MonadControlIO m => (m () -> IO ()) -> Assertion
-case_catch run = do
-    i <- newIORef one
-    run $ (do
-        liftIO $ writeIORef i 2
-        throw Exc) `catch` (\Exc -> liftIO $ writeIORef i 3)
-    j <- readIORef i
-    j @?= 3
-
-case_bracket :: MonadControlIO m => (m () -> IO ()) -> Assertion
-case_bracket run = do
-    i <- newIORef one
-    ignore $ run $ bracket
-        (liftIO $ writeIORef i 2)
-        (\() -> liftIO $ writeIORef i 4)
-        (\() -> liftIO $ writeIORef i 3)
-    j <- readIORef i
-    j @?= 4
-
-case_bracket_ :: MonadControlIO m => (m () -> IO ()) -> Assertion
-case_bracket_ run = do
-    i <- newIORef one
-    ignore $ run $ bracket_
-        (liftIO $ writeIORef i 2)
-        (liftIO $ writeIORef i 4)
-        (liftIO $ writeIORef i 3)
-    j <- readIORef i
-    j @?= 4
-
-case_onException :: MonadControlIO m => (m () -> IO ()) -> Assertion
-case_onException run = do
-    i <- newIORef one
-    ignore $ run $ onException
-        (liftIO (writeIORef i 2) >> error "ignored")
-        (liftIO $ writeIORef i 3)
-    j <- readIORef i
-    j @?= 3
-    ignore $ run $ onException
-        (liftIO $ writeIORef i 4)
-        (liftIO $ writeIORef i 5)
-    k <- readIORef i
-    k @?= 4
-
-case_throwError :: Assertion
-case_throwError = do
-    i <- newIORef one
-    Left "throwError" <- runErrorT $
-        (liftIO (writeIORef i 2) >> throwError "throwError")
-        `finally`
-        (liftIO $ writeIORef i 3)
-    j <- readIORef i
-    j @?= 3
-
-case_tell :: Assertion
-case_tell = do
-    i <- newIORef one
-    ((), w) <- runWriterT $ bracket_
-        (liftIO (writeIORef i 2) >> tell [1 :: Int])
-        (liftIO (writeIORef i 4) >> tell [3])
-        (liftIO (writeIORef i 3) >> tell [2])
-    j <- readIORef i
-    j @?= 4
-    w @?= [2]
-
-    ((), w') <- runWriterT $ bracket
-        (liftIO (writeIORef i 5) >> tell [5 :: Int])
-        (const $ liftIO (writeIORef i 7) >> tell [7])
-        (const $ liftIO (writeIORef i 6) >> tell [6])
-    j' <- readIORef i
-    j' @?= 7
-    w' @?= [5, 6]
