diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,4 +1,11 @@
 # Changelog for polysemy-readline
 
+## Unreleased Changes
+
+## 0.2.0.0 - July 27th 2021
+- Add `runReadlineFinal` and improved instructions for mitigating lack of
+  support for repl history when using `runReadline` in the simplest way
+  possible.
+
 ## 0.1.0.0 — June 24th 2021
 - Release candidate for Hackage.
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,14 +1,14 @@
 # polysemy-readline
 [![GitHub Actions](https://github.com/lehmacdj/polysemy-readline/actions/workflows/ci.yml/badge.svg)](https://github.com/lehmacdj/polysemy-readline/actions/workflows/ci.yml)
-[![Hackage](http://img.shields.io/hackage/v/polsyemy-readline.svg)](http://img.shields.io/hackage/v/polsyemy-readline.svg)
+[![Hackage](https://img.shields.io/hackage/v/polysemy-readline.svg?logo=haskell)](https://hackage.haskell.org/package/polysemy-readline)
 
-This package provides a [polysemy](https://github.com/polysemy-research/polysemy#readme) effect that provides most of the functionality of [haskeline](https://github.com/judah/haskeline#readme). See Haskeline's documentation for usage information.
+This package provides a [polysemy](https://github.com/polysemy-research/polysemy#readme) effect that provides most of the functionality of [haskeline](https://github.com/judah/haskeline#readme). See Haskeline's documentation for additional usage information.
 
 ## Contributions
-Issues or PRs are welcome. In particular there are a number of things that I don't use frequently enough from Haskeline to justify working on or just haven't gotten around to implementing yet:
+Bug reports and PRs are welcome. In particular there are a number of things that I don't use frequently enough from Haskeline to justify working on or just haven't gotten around to implementing yet:
 - interrupt handling: `withInterrupt`, `handleInterrupt`
-- pure interpreter for using in tests
-- additional interpreters matching the `run*` functions for `InputT`
+- pure interpreter for use in tests
 - support for older versions of Haskeline (currently only 0.8.1+ is supported)
-- version bumps for things that already compile but aren't allowed
-PRs for any of these things would be greatly appreciated or I might get around to implementing them myself later 🙂.
+- version bumps for dependencies that already compile but aren't allowed
+
+PRs for any of these things would be greatly appreciated or I will try to get around to implementing them myself later 🙂.
diff --git a/examples/Echo.hs b/examples/Echo.hs
new file mode 100644
--- /dev/null
+++ b/examples/Echo.hs
@@ -0,0 +1,22 @@
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE GADTs #-}
+
+module Main where
+
+import Polysemy
+import Polysemy.Readline
+
+repl :: Member Readline r => Sem r ()
+repl = do
+  mline <- getInputLine "> "
+  case mline of
+    Nothing -> pure ()
+    Just line -> outputStrLn line >> repl
+
+main :: IO ()
+main =
+  runInputT defaultSettings
+    . runFinal
+    . embedToFinal
+    . interpretReadlineAsInputT
+    $ repl
diff --git a/polysemy-readline.cabal b/polysemy-readline.cabal
--- a/polysemy-readline.cabal
+++ b/polysemy-readline.cabal
@@ -2,7 +2,7 @@
 
 name:           polysemy-readline
 synopsis:       Readline effect for polysemy.
-version:        0.1.0.0
+version:        0.2.0.0
 category:       User Interfaces, Effect
 homepage:       https://github.com/lehmacdj/polysemy-readline#readme
 bug-reports:    https://github.com/lehmacdj/polysemy-readline/issues
@@ -51,6 +51,17 @@
       Paths_polysemy_readline
   hs-source-dirs:
       src
+
+executable echo-repl
+  import: common-options
+  import: exe-options
+  main-is: Echo.hs
+  other-modules:
+      Paths_polysemy_readline
+  autogen-modules:
+      Paths_polysemy_readline
+  build-depends: polysemy-readline
+  hs-source-dirs: examples
 
 test-suite polysemy-readline-test
   import: common-options
diff --git a/src/Polysemy/Readline.hs b/src/Polysemy/Readline.hs
--- a/src/Polysemy/Readline.hs
+++ b/src/Polysemy/Readline.hs
@@ -23,11 +23,13 @@
 
     -- * Interpreters
     runReadline,
+    runReadlineFinal,
     interpretReadlineAsInputT,
 
     -- * Re-exports from @haskeline@
-    H.Settings,
+    H.Settings (..),
     H.defaultSettings,
+    H.runInputT,
   )
 where
 
@@ -56,9 +58,22 @@
 outputStrLn :: Member Readline r => String -> Sem r ()
 outputStrLn str = outputStr (str <> "\n")
 
--- | The standard way to run a Readline effect. Should be sufficient for
--- most use cases. If you want to modify the Behavior or Prefs of InputT use
--- interpretReadlineAsInputT instead.
+-- | The simplest way to run a Readline effect. Immediately eliminates the
+-- resulting 'H.InputT'. There is one problem with this approach however.
+-- Internal details of polysemy cause 'H.runInputT' to be run once per effect
+-- call (e.g. @getInputLine "> " >> getInputLine "> "@ will result in two calls
+-- to 'H.runInputT'), and the History state of consecutive runs is not
+-- preserved unless there is a history file. If you want history for your repl
+-- there are therefore two recommended approaches:
+--
+-- * Provide a history file in the settings you specify. e.g.
+-- @runReadline ('H.defaultSettings' {historyFile = Just ".repl_history"})@.
+-- This is the easiest approach but technically suboptimal because the history
+-- file will be read between every different primitive effect call.
+-- * Use 'interpretReadlineAsInputT' or 'runReadlineFinal' and keep the
+-- `H.InputT` around until after using 'runFinal' to escape polysemy land. This
+-- way state can be preserved between effect calls. For an example using this
+-- see @examples/Echo.hs@.
 runReadline ::
   forall m r a.
   (MonadIO m, MonadMask m, Member (Embed m) r) =>
@@ -67,6 +82,19 @@
   Sem r a
 runReadline settings =
   runEmbedded (H.runInputT settings)
+    . interpretReadlineAsInputT
+    . raiseUnder @(Embed (H.InputT m))
+
+-- | Interpreter for the somewhat common case of wanting to keep InputT around
+-- until after 'runFinal' to ensure that state is preserved between subsequent
+-- effects.
+runReadlineFinal ::
+  forall m r a.
+  (MonadIO m, MonadMask m, Member (Final (H.InputT m)) r) =>
+  Sem (Readline : r) a ->
+  Sem r a
+runReadlineFinal =
+  embedToFinal
     . interpretReadlineAsInputT
     . raiseUnder @(Embed (H.InputT m))
 
