diff --git a/ChangeLog.md b/ChangeLog.md
new file mode 100644
--- /dev/null
+++ b/ChangeLog.md
@@ -0,0 +1,3 @@
+* **0.5.0**:
+  2024-01-15: Removed MonadTrans instance, replaced with liftTardisT
+
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2012, Dan Burton
+Copyright (c) 2012-2026, Dan Burton
 
 All rights reserved.
 
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,34 @@
+# TardisT
+
+![build status](https://github.com/DanBurton/tardis/actions/workflows/haskell.yml/badge.svg?branch=master)
+
+The State monad allows you
+to send information forwards to the future,
+or to receive such information from the past.
+The Reverse State monad allows you to do the reverse:
+send information backwards to the past,
+or receive information from the future. 
+
+TardisT is a monad transformer
+that provides state operations that allow you
+to send information to both the future *and* the past,
+as well as receive information from both directions.
+It is isomorphic to a StateT on top of a ReverseStateT,
+or vice-versa.
+
+See test/Example.hs for an example.
+
+----
+
+This was inspired by Luke Palmer's blog post on
+the "reverse state monad".
+
+http://lukepalmer.wordpress.com/2008/08/10/mindfuck-the-reverse-state-monad/
+
+See also:
+
+http://panicsonic.blogspot.com/2007/12/backwards-state-or-power-of-laziness.html
+
+----
+
+(c) 2012-2026 Dan Burton
diff --git a/src/Control/Monad/Tardis.hs b/src/Control/Monad/Tardis.hs
--- a/src/Control/Monad/Tardis.hs
+++ b/src/Control/Monad/Tardis.hs
@@ -61,14 +61,14 @@
     while setting the backwards-traveling state will affect the /past/.
     Take a look at how Monadic bind is implemented for 'TardisT':
 
-> m >>= f  = TardisT $ \ ~(bw, fw) -> do
->   rec (x,  ~(bw'', fw' )) <- runTardisT m (bw', fw)
->       (x', ~(bw' , fw'')) <- runTardisT (f x) (bw, fw')
+> m >>= f  = TardisT $ \ ~(bw, fw) -> mdo
+>   (x,  ~(bw'', fw' )) <- runTardisT m (bw', fw)
+>   (x', ~(bw' , fw'')) <- runTardisT (f x) (bw, fw')
 >   return (x', (bw'', fw''))
 
     Like the Reverse State monad transformer, TardisT's Monad instance
     requires that the monad it transforms is an instance of MonadFix,
-    as is evidenced by the use of @rec@.
+    as is evidenced by the use of @mdo@.
     Notice how the forwards-traveling state travels /normally/:
     first it is fed to @m@, producing @fw'@, and then it is fed to @f x@,
     producing @fw''@. The backwards-traveling state travels in the opposite
diff --git a/src/Control/Monad/Tardis/Class.hs b/src/Control/Monad/Tardis/Class.hs
--- a/src/Control/Monad/Tardis/Class.hs
+++ b/src/Control/Monad/Tardis/Class.hs
@@ -66,13 +66,12 @@
 
   -- | A Tardis is merely a pure state transformation.
   tardis :: ((bw, fw) -> (a, (bw, fw))) -> m a
-  tardis f = do
-    rec
-      let (a, (future', past')) = f (future, past)
-      sendPast future'
-      past <- getPast
-      future <- getFuture
-      sendFuture past'
+  tardis f = mdo
+    let (a, (future', past')) = f (future, past)
+    sendPast future'
+    past <- getPast
+    future <- getFuture
+    sendFuture past'
     return a
 
 -- | Modify the forwards-traveling state
@@ -83,10 +82,9 @@
 -- | Modify the backwards-traveling state
 -- as it passes through from future to past.
 modifyBackwards :: MonadTardis bw fw m => (bw -> bw) -> m ()
-modifyBackwards f = do
-  rec
-    sendPast (f x)
-    x <- getFuture
+modifyBackwards f = mdo
+  sendPast (f x)
+  x <- getFuture
   return ()
 
 -- | Retrieve a specific view of the forwards-traveling state.
diff --git a/src/Control/Monad/Trans/Tardis.hs b/src/Control/Monad/Trans/Tardis.hs
--- a/src/Control/Monad/Trans/Tardis.hs
+++ b/src/Control/Monad/Trans/Tardis.hs
@@ -1,4 +1,5 @@
 {-# LANGUAGE RecursiveDo                     #-}
+{-# LANGUAGE TupleSections #-}
 
 -- | The data definition of a "TardisT"
 -- as well as its primitive operations,
@@ -35,6 +36,7 @@
 
     -- * Other
   , mapTardisT
+  , liftTardisT
   , noState
   ) where
 
@@ -99,6 +101,10 @@
 execTardis :: Tardis bw fw a -> (bw, fw) -> (bw, fw)
 execTardis t = runIdentity . execTardisT t
 
+-- | An action in the underlying monad (or just functor, really)
+-- can also be used in a Tardis by lifting it in.
+liftTardisT :: (Functor m) => m a -> TardisT bw fw m a
+liftTardisT m = TardisT $ \s -> fmap (,s) m
 
 -- | A function that operates on the internal representation of a Tardis
 -- can also be used on a Tardis.
@@ -119,28 +125,21 @@
 -------------------------------------------------
 
 instance MonadFix m => Monad (TardisT bw fw m) where
-  return x = tardis $ \s -> (x, s)
-  m >>= f  = TardisT $ \ ~(bw, fw) -> do
-    rec (x,  ~(bw'', fw' )) <- runTardisT m (bw', fw)
-        (x', ~(bw' , fw'')) <- runTardisT (f x) (bw, fw')
+  m >>= f  = TardisT $ \ ~(bw, fw) -> mdo
+    (x,  ~(bw'', fw' )) <- runTardisT m (bw', fw)
+    (x', ~(bw' , fw'')) <- runTardisT (f x) (bw, fw')
     return (x', (bw'', fw''))
 
 instance MonadFix m => Functor (TardisT bw fw m) where
   fmap = liftM
 
 instance MonadFix m => Applicative (TardisT bw fw m) where
-  pure = return
+  pure x = tardis $ \s -> (x, s)
   (<*>) = ap
 
-
-instance MonadTrans (TardisT bw fw) where
-  lift m = TardisT $ \s -> do
-    x <- m
-    return (x, s)
-
 instance MonadFix m => MonadFix (TardisT bw fw m) where
-  mfix f = TardisT $ \s -> do
-    rec (x, s') <- runTardisT (f x) s
+  mfix f = TardisT $ \s -> mdo
+    (x, s') <- runTardisT (f x) s
     return (x, s')
 
 instance MFunctor (TardisT bw fw) where
@@ -194,10 +193,9 @@
 -- | Modify the backwards-traveling state
 -- as it passes through from future to past.
 modifyBackwards :: MonadFix m => (bw -> bw) -> TardisT bw fw m ()
-modifyBackwards f = do
-  rec
-    sendPast (f x)
-    x <- getFuture
+modifyBackwards f = mdo
+  sendPast (f x)
+  x <- getFuture
   return ()
 
 
diff --git a/tardis.cabal b/tardis.cabal
--- a/tardis.cabal
+++ b/tardis.cabal
@@ -1,5 +1,5 @@
 name:                tardis
-version:             0.4.4.0
+version:             0.5.0.1
 synopsis:            Bidirectional state monad transformer
 homepage:            https://github.com/DanBurton/tardis
 bug-reports:         https://github.com/DanBurton/tardis/issues
@@ -10,6 +10,8 @@
 category:            Control
 build-type:          Simple
 cabal-version:       >=1.10
+tested-with:         GHC == 9.14.1, GHC == 9.12.2, GHC == 9.10.3, GHC == 9.8.4, GHC == 9.6.7, GHC == 9.4.8
+extra-source-files:  README.md, ChangeLog.md
 
 description:
   A Tardis is a combination of both a forwards and a backwards
@@ -30,6 +32,7 @@
   build-depends:       base >= 4.8 && < 5
                      , mtl==2.*
                      , mmorph==1.*
+  ghc-options: -Wcompat -Wall -Wno-unused-imports
 
 test-suite tardis-tests
   default-language:  Haskell2010
@@ -39,12 +42,8 @@
   build-depends:     base >= 4.8 && < 5
                    , tardis
   other-modules:   Example
+  ghc-options: -Wcompat -Wall -Wno-unrecognised-warning-flags -Wno-x-partial
 
 source-repository head
   type:     git
-  location: git://github.com/DanBurton/tardis.git
-
-source-repository this
-  type:     git
-  location: git://github.com/DanBurton/tardis.git
-  tag:      tardis-0.4.1.0
+  location: https://github.com/DanBurton/tardis.git
diff --git a/test/Example.hs b/test/Example.hs
--- a/test/Example.hs
+++ b/test/Example.hs
@@ -38,17 +38,16 @@
     PreviousScores scores <- getPast
     let score = head scores
     return $ (finalFrameScore + score) : scores
-  go (f : fs) = do
-    rec
-      sendPast $ NextThrows throws'
-      PreviousScores scores <- getPast
-      let score = head scores
-      sendFuture $ PreviousScores (score' : scores)
-      NextThrows ~(nextThrow1, nextThrow2) <- getFuture
-      let (score', throws') = case f of
-            Strike    -> (score + 10 + nextThrow1 + nextThrow2, (10, nextThrow1))
-            Spare n   -> (score + 10 + nextThrow1,              (n, 10 - n))
-            Frame n m -> (score + n + m,                        (n, m))
+  go (f : fs) = mdo
+    sendPast $ NextThrows throws'
+    PreviousScores scores <- getPast
+    let score = head scores
+    sendFuture $ PreviousScores (score' : scores)
+    NextThrows ~(nextThrow1, nextThrow2) <- getFuture
+    let (score', throws') = case f of
+          Strike    -> (score + 10 + nextThrow1 + nextThrow2, (10, nextThrow1))
+          Spare n   -> (score + 10 + nextThrow1,              (n, 10 - n))
+          Frame n m -> (score + n + m,                        (n, m))
     go fs
 
   finalFrameScore = case lastFrame game of
diff --git a/test/Main.hs b/test/Main.hs
--- a/test/Main.hs
+++ b/test/Main.hs
@@ -7,4 +7,6 @@
     putStrLn $ "Expected: " <> show expectedScores
     putStrLn $ "Actual: " <> show actualScores
     exitFailure
-  True -> exitSuccess
+  True -> do
+    putStrLn "Test passed."
+    exitSuccess
