diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,3 +1,17 @@
+## 0.4.1.0 (2023-03-09)
+
+`Will (..)` and `Vitality (..)` are now re-exported from
+`Fold.Shortcut` and `Fold.ShortcutNonempty`; previously these
+were only available from `Fold.Shortcut.Type` and
+`Fold.ShortcutNonempty.Type`.
+
+A new utility `repeatedly` has been added to `Fold.Pure`,
+`Fold.Nonempty`, `Fold.Shortcut`, and `Fold.ShortcutNonempty`.
+
+New utilities `motivate`, `premap`, and `withVitality` and a new
+type alias `Vitality'` have been added to `Fold.Shortcut` and
+`Fold.ShortcutNonempty`.
+
 ## 0.4.0.0 (2023-03-08)
 
 Changed `ShortcutFold` from
diff --git a/gambler.cabal b/gambler.cabal
--- a/gambler.cabal
+++ b/gambler.cabal
@@ -1,7 +1,7 @@
 cabal-version: 3.0
 
 name: gambler
-version: 0.4.0.0
+version: 0.4.1.0
 
 category: Streaming
 synopsis: Composable, streaming, and efficient left folds
@@ -9,7 +9,7 @@
     memory, and you can combine folds using @Applicative@ style to derive new
     folds that still traverse the list only once.
 
-author: Gabriella Gonzalez
+author: Gabriella Gonzalez, Chris Martin
 maintainer: Chris Martin, Julie Moronuki
 
 license: BSD-3-Clause
diff --git a/source/Fold.hs b/source/Fold.hs
--- a/source/Fold.hs
+++ b/source/Fold.hs
@@ -73,7 +73,7 @@
 effectfulToNonempty = ConvertTo.Nonempty.effectfulFold
 
 {-| Turn a fold that requires at least one input into a fold that returns
-'Data.Maybe.Nothing' when there are no inputs -}
+    'Data.Maybe.Nothing' when there are no inputs -}
 nonemptyToEmpty :: NonemptyFold a b -> Fold a (Maybe b)
 nonemptyToEmpty = ConvertTo.Pure.nonemptyFold
 
@@ -86,7 +86,7 @@
 effectfulToPure = ConvertTo.Pure.effectfulFold
 
 {-| Turn a nonempty fold that requires at least one input into a fold that
-returns 'Data.Maybe.Nothing' when there are no inputs -}
+    returns 'Data.Maybe.Nothing' when there are no inputs -}
 nonemptyToEffectful :: Monad m =>
     NonemptyFold a b -> EffectfulFold m a (Maybe b)
 nonemptyToEffectful = ConvertTo.Effectful.nonemptyFold
@@ -100,16 +100,16 @@
 reverseNonemptyList = Nonempty.reverseList
 
 {-| Allows to continue feeding a fold even after passing it to a function
-that closes it -}
+    that closes it -}
 duplicateFold :: Fold a b -> Fold a (Fold a b)
 duplicateFold = Pure.duplicate
 
 {-| Allows to continue feeding a fold even after passing it to a function
-that closes it -}
+    that closes it -}
 duplicateNonemptyFold :: NonemptyFold a b -> NonemptyFold a (Fold a b)
 duplicateNonemptyFold = Nonempty.duplicate
 
 {-| Allows to continue feeding an effectful fold even after passing it to a
-function that closes it -}
+    function that closes it -}
 duplicateEffectfulFold :: Applicative m => EffectfulFold m a b -> EffectfulFold m a (EffectfulFold m a b)
 duplicateEffectfulFold = Effectful.duplicate
diff --git a/source/Fold/Effectful/Conversion.hs b/source/Fold/Effectful/Conversion.hs
--- a/source/Fold/Effectful/Conversion.hs
+++ b/source/Fold/Effectful/Conversion.hs
@@ -22,7 +22,7 @@
     }
 
 {-| Turn a nonempty fold that requires at least one input into a fold that
-returns 'Data.Maybe.Nothing' when there are no inputs -}
+    returns 'Data.Maybe.Nothing' when there are no inputs -}
 nonemptyFold :: Monad m => NonemptyFold a b -> EffectfulFold m a (Maybe b)
 nonemptyFold x = fold (Pure.nonemptyFold x)
 
diff --git a/source/Fold/Effectful/Examples/Boring.hs b/source/Fold/Effectful/Examples/Boring.hs
--- a/source/Fold/Effectful/Examples/Boring.hs
+++ b/source/Fold/Effectful/Examples/Boring.hs
@@ -32,7 +32,7 @@
 import qualified Fold.Effectful.Conversion as Convert
 
 {-| Start with the first input, append each new input on the right
-with the given function -}
+    with the given function -}
 magma :: (a -> a -> a) -> Monad m => EffectfulFold m a (Maybe a)
 magma step = Convert.nonemptyFold (Nonempty.magma step)
 
diff --git a/source/Fold/Effectful/Examples/Interesting.hs b/source/Fold/Effectful/Examples/Interesting.hs
--- a/source/Fold/Effectful/Examples/Interesting.hs
+++ b/source/Fold/Effectful/Examples/Interesting.hs
@@ -16,7 +16,7 @@
 effect f = effectMonoid (\a -> void (f a))
 
 {-| Performs an action for each input, monoidally combining the results
-from all the actions. -}
+    from all the actions -}
 effectMonoid ::  (Monoid w, Monad m) => (a -> m w) -> EffectfulFold m a w
 effectMonoid act = EffectfulFold
     { initial = Applicative.pure mempty
diff --git a/source/Fold/Effectful/Run.hs b/source/Fold/Effectful/Run.hs
--- a/source/Fold/Effectful/Run.hs
+++ b/source/Fold/Effectful/Run.hs
@@ -9,7 +9,7 @@
 import qualified Data.Foldable as F
 
 {-| Fold an listlike container to an action that produces a single summary
-result -}
+    result -}
 run :: Foldable f => Monad m => EffectfulFold m a b -> f a -> m b
 run EffectfulFold{ initial, step, extract } as0 = do
     x0 <- initial
diff --git a/source/Fold/Effectful/Type.hs b/source/Fold/Effectful/Type.hs
--- a/source/Fold/Effectful/Type.hs
+++ b/source/Fold/Effectful/Type.hs
@@ -9,7 +9,7 @@
 
 import qualified Strict
 
-{- | Processes inputs of type @a@ and results in an effectful value of type @m b@ -}
+{-| Processes inputs of type @a@ and results in an effectful value of type @m b@ -}
 data EffectfulFold m a b = forall x. EffectfulFold
     { initial :: m x
     , step :: x -> a -> m x
diff --git a/source/Fold/Effectful/Utilities.hs b/source/Fold/Effectful/Utilities.hs
--- a/source/Fold/Effectful/Utilities.hs
+++ b/source/Fold/Effectful/Utilities.hs
@@ -10,7 +10,7 @@
 import Prelude ((-))
 
 {-| Shift an effectful fold from one monad to another with a morphism such as
-@lift@ or @liftIO@ -}
+    @lift@ or @liftIO@ -}
 hoist :: (forall x . m x -> n x) -> EffectfulFold m a b -> EffectfulFold n a b
 hoist f EffectfulFold{ initial, step, extract } = EffectfulFold
     { initial = f initial
@@ -19,7 +19,7 @@
     }
 
 {-| Allows to continue feeding an effectful fold even after passing it to a
-function that closes it -}
+    function that closes it -}
 duplicate :: Applicative m => EffectfulFold m a b -> EffectfulFold m a (EffectfulFold m a b)
 duplicate EffectfulFold{ initial, step, extract } = EffectfulFold
     { initial
diff --git a/source/Fold/Nonempty.hs b/source/Fold/Nonempty.hs
--- a/source/Fold/Nonempty.hs
+++ b/source/Fold/Nonempty.hs
@@ -17,7 +17,7 @@
 
     {- * Conversion -} fold, effectfulFold, shortcutFold, shortcutNonemptyFold,
 
-    {- * Utilities -} duplicate, premap, nest,
+    {- * Utilities -} duplicate, repeatedly, premap, nest,
   )
   where
 
diff --git a/source/Fold/Nonempty/Conversion.hs b/source/Fold/Nonempty/Conversion.hs
--- a/source/Fold/Nonempty/Conversion.hs
+++ b/source/Fold/Nonempty/Conversion.hs
@@ -15,13 +15,13 @@
 import qualified Fold.ShortcutNonempty.Type as ShortcutNonempty
 
 {-| Turn a regular fold that allows empty input into a fold that
-requires at least one input -}
+    requires at least one input -}
 fold :: Fold a b -> NonemptyFold a b
 fold Fold{ Fold.initial, Fold.step, Fold.extract } =
     NonemptyFold{ initial = step initial, step, extract }
 
 {-| Turn an effectful fold into a pure fold that requires at least
-one input -}
+    one input -}
 effectfulFold :: EffectfulFold Identity a b -> NonemptyFold a b
 effectfulFold x = fold (Fold.Conversion.effectfulFold x)
 
diff --git a/source/Fold/Nonempty/Examples/Interesting.hs b/source/Fold/Nonempty/Examples/Interesting.hs
--- a/source/Fold/Nonempty/Examples/Interesting.hs
+++ b/source/Fold/Nonempty/Examples/Interesting.hs
@@ -19,7 +19,7 @@
 import qualified Strict
 
 {-| Start with the first input, append each new input on the right
-with the given function -}
+    with the given function -}
 magma :: (a -> a -> a) -> NonemptyFold a a
 magma step = NonemptyFold{ initial = id, step, extract = id }
 
diff --git a/source/Fold/Nonempty/Type.hs b/source/Fold/Nonempty/Type.hs
--- a/source/Fold/Nonempty/Type.hs
+++ b/source/Fold/Nonempty/Type.hs
@@ -7,7 +7,7 @@
 
 import qualified Strict
 
-{- | Processes at least one input of type @a@ and results in a value of type @b@ -}
+{-| Processes at least one input of type @a@ and results in a value of type @b@ -}
 data NonemptyFold a b = forall x. NonemptyFold
     { initial :: a -> x
     , step :: x -> a -> x
diff --git a/source/Fold/Nonempty/Utilities.hs b/source/Fold/Nonempty/Utilities.hs
--- a/source/Fold/Nonempty/Utilities.hs
+++ b/source/Fold/Nonempty/Utilities.hs
@@ -7,15 +7,18 @@
 import Fold.Pure.Type (Fold (Fold))
 
 import qualified Fold.Pure.Type as Pure
+import qualified Fold.Pure.Utilities as Pure
+import qualified Fold.Pure.Run as Pure.Run
+import qualified Fold.Nonempty.Conversion as Nonempty
 
 {-| Allows to continue feeding a fold even after passing it to a function
-that closes it -}
+    that closes it -}
 duplicate :: NonemptyFold a b -> NonemptyFold a (Fold a b)
 duplicate NonemptyFold{ initial, step, extract } =
     NonemptyFold{ initial, step, extract = \x -> Fold
         { Pure.initial = x, Pure.step, Pure.extract } }
 
-{-| @(premap f folder)@ returns a new fold where @f@ is applied at each step -}
+{-| Applies a function to each input before processing -}
 premap :: (a -> b) -> NonemptyFold b r -> NonemptyFold a r
 premap f NonemptyFold{ initial, step, extract } =
     NonemptyFold{ initial = \a -> initial (f a),
@@ -25,3 +28,17 @@
 nest :: Applicative f => NonemptyFold a b -> NonemptyFold (f a) (f b)
 nest NonemptyFold{ initial, step, extract } = NonemptyFold
     { initial = fmap initial, step = liftA2 step, extract = fmap extract }
+
+{-| Convert a nonempty fold for a single item (@x@) into a
+    nonempty fold for nonempty lists of items (@xs@) -}
+repeatedly :: forall x xs result.
+    (forall b. NonemptyFold x b -> xs -> b)
+        -- ^ A witness to the fact that @xs@ is a nonempty list of @x@
+    -> NonemptyFold x result
+    -> NonemptyFold xs result
+repeatedly runXs foldX =
+  NonemptyFold
+    { initial = runXs (duplicate foldX)
+    , step = \f -> runXs (Nonempty.fold (Pure.duplicate f))
+    , extract = \f -> Pure.Run.run f []
+    }
diff --git a/source/Fold/Pure.hs b/source/Fold/Pure.hs
--- a/source/Fold/Pure.hs
+++ b/source/Fold/Pure.hs
@@ -17,7 +17,7 @@
 
     {- * Conversion -} effectfulFold, nonemptyFold, shortcutFold, shortcutNonemptyFold,
 
-    {- * Utilities -} duplicate, premap, prefilter, predropWhile, drop, nest,
+    {- * Utilities -} duplicate, repeatedly, premap, prefilter, predropWhile, drop, nest,
   )
   where
 
diff --git a/source/Fold/Pure/Conversion.hs b/source/Fold/Pure/Conversion.hs
--- a/source/Fold/Pure/Conversion.hs
+++ b/source/Fold/Pure/Conversion.hs
@@ -30,7 +30,7 @@
       }
 
 {-| Turn a fold that requires at least one input into a fold that returns
-'Data.Maybe.Nothing' when there are no inputs -}
+    'Data.Maybe.Nothing' when there are no inputs -}
 nonemptyFold :: NonemptyFold a b -> Fold a (Maybe b)
 nonemptyFold
   NonemptyFold{ Nonempty.initial, Nonempty.step, Nonempty.extract } =
diff --git a/source/Fold/Pure/Run.hs b/source/Fold/Pure/Run.hs
--- a/source/Fold/Pure/Run.hs
+++ b/source/Fold/Pure/Run.hs
@@ -19,7 +19,7 @@
     cons a k x = k $! step x a
 
 {-| Rather than only obtain a single final result, scanning gives a running
-total that shows the intermediate result at each step along the way
+    total that shows the intermediate result at each step along the way
 
 @
 scan 'Fold.Pure.Examples.monoid' ["a", "b", "c"] = ["","a","ab","abc"]
diff --git a/source/Fold/Pure/Type.hs b/source/Fold/Pure/Type.hs
--- a/source/Fold/Pure/Type.hs
+++ b/source/Fold/Pure/Type.hs
@@ -7,7 +7,7 @@
 
 import qualified Strict
 
-{- | Processes inputs of type @a@ and results in a value of type @b@ -}
+{-| Processes inputs of type @a@ and results in a value of type @b@ -}
 data Fold a b = forall x. Fold
     { initial :: x
     , step :: x -> a -> x
diff --git a/source/Fold/Pure/Utilities.hs b/source/Fold/Pure/Utilities.hs
--- a/source/Fold/Pure/Utilities.hs
+++ b/source/Fold/Pure/Utilities.hs
@@ -5,13 +5,14 @@
 import Control.Applicative (Applicative, liftA2, pure)
 import Data.Bool (Bool (False, True), (&&))
 import Data.Functor (fmap)
+import Fold.Pure.Run (run)
 import Numeric.Natural (Natural)
 import Prelude ((-))
 
 import qualified Strict
 
 {-| Allows to continue feeding a fold even after passing it to a function
-that closes it -}
+    that closes it -}
 duplicate :: Fold a b -> Fold a (Fold a b)
 duplicate Fold{ initial, step, extract } =
     Fold{ initial, step, extract = \x -> Fold{ initial = x, step, extract } }
@@ -51,3 +52,17 @@
 nest :: Applicative f => Fold a b -> Fold (f a) (f b)
 nest Fold{ initial, step, extract } = Fold
     { initial = pure initial, step = liftA2 step, extract = fmap extract }
+
+{-| Convert a fold for a single item (@x@) into a fold for
+    lists of items (@xs@) -}
+repeatedly :: forall x xs result.
+    (forall b. Fold x b -> xs -> b)
+        -- ^ A witness to the fact that @xs@ is a list of @x@
+    -> Fold x result
+    -> Fold xs result
+repeatedly runXs foldX =
+  Fold
+    { initial = run (duplicate foldX) []
+    , step = \f -> runXs (duplicate f)
+    , extract = \f -> run f []
+    }
diff --git a/source/Fold/Shortcut.hs b/source/Fold/Shortcut.hs
--- a/source/Fold/Shortcut.hs
+++ b/source/Fold/Shortcut.hs
@@ -1,6 +1,6 @@
 module Fold.Shortcut
   (
-    {- * Type -} ShortcutFold (..),
+    {- * Type -} ShortcutFold (..), Will (..), Vitality (..), Vitality',
 
     {- * Run -} run,
 
@@ -17,7 +17,7 @@
 
     {- * Conversion -} fold, effectfulFold, nonemptyFold, shortcutNonemptyFold,
 
-    {- * Utilities -} demotivate, duplicate,
+    {- * Utilities -} motivate, demotivate, duplicate, repeatedly, premap, withVitality,
   )
   where
 
diff --git a/source/Fold/Shortcut/Type.hs b/source/Fold/Shortcut/Type.hs
--- a/source/Fold/Shortcut/Type.hs
+++ b/source/Fold/Shortcut/Type.hs
@@ -1,7 +1,7 @@
 module Fold.Shortcut.Type
   (
     ShortcutFold (..),
-    Will (..), Vitality (..),
+    Will (..), Vitality (..), Vitality',
   )
   where
 
@@ -9,13 +9,13 @@
 import Data.Functor (Functor, fmap)
 import Data.Monoid (Monoid, mempty)
 import Data.Semigroup (Semigroup, (<>))
-import Strict (Will (..), Vitality (..))
+import Strict (Will (..), Vitality (..), Vitality')
 import Data.Void (absurd)
 
 import qualified Strict
 
-{- | Processes inputs of type @a@, has the ability to halt midway
-     through the stream, and results in a value of type @b@ -}
+{-| Processes inputs of type @a@, has the ability to halt midway
+    through the stream, and results in a value of type @b@ -}
 data ShortcutFold a b = forall x y. ShortcutFold
     { initial :: Vitality x y
     , step :: y -> a -> Vitality x y
diff --git a/source/Fold/Shortcut/Utilities.hs b/source/Fold/Shortcut/Utilities.hs
--- a/source/Fold/Shortcut/Utilities.hs
+++ b/source/Fold/Shortcut/Utilities.hs
@@ -2,10 +2,19 @@
 
 import Fold.Shortcut.Type
 
-import Strict (willSave)
+import Fold.Shortcut.Run (run)
+import Strict (willSave, willBoost, getVitality')
 
 import qualified Strict
 
+motivate :: ShortcutFold a b -> ShortcutFold a b
+motivate ShortcutFold{ initial, step, extract } =
+  ShortcutFold
+    { initial = willBoost initial
+    , step = \x a -> willBoost (step x a)
+    , extract
+    }
+
 {-| Causes a shortcut fold to stop once it becomes ambivalent -}
 demotivate :: ShortcutFold a b -> ShortcutFold a b
 demotivate ShortcutFold{ initial, step, extract } =
@@ -20,7 +29,7 @@
     }
 
 {-| Allows to continue feeding a fold even after passing it to a function
-that closes it -}
+    that closes it -}
 duplicate :: ShortcutFold a b -> ShortcutFold a (ShortcutFold a b)
 duplicate ShortcutFold{ initial, step, extract } =
   ShortcutFold
@@ -28,3 +37,32 @@
     , step
     , extract = \v -> ShortcutFold{ initial = v, step, extract }
     }
+
+withVitality :: ShortcutFold a b -> ShortcutFold a (Vitality' b)
+withVitality ShortcutFold{ initial, step, extract } =
+  ShortcutFold
+    { initial
+    , step
+    , extract = \v -> let x = extract v in case v of
+        Alive w _ -> Alive w x
+        Dead _ -> Dead x
+    }
+
+{-| Convert a fold for a single item (@x@) into a fold for lists
+    of items (@xs@) -}
+repeatedly :: forall x xs result.
+    (forall b. ShortcutFold x b -> xs -> b)
+        -- ^ A witness to the fact that @xs@ is a list of @x@
+    -> ShortcutFold x result
+    -> ShortcutFold xs result
+repeatedly runXs foldX =
+  ShortcutFold
+    { initial = run (withVitality (duplicate foldX)) []
+    , step = \f xs -> runXs (withVitality (duplicate f)) xs
+    , extract = \f -> run (getVitality' f) []
+    }
+
+{-| Applies a function to each input before processing -}
+premap :: (a -> b) -> ShortcutFold b r -> ShortcutFold a r
+premap f ShortcutFold{ initial, step, extract } =
+    ShortcutFold{ initial, step = \x a -> step x (f a), extract }
diff --git a/source/Fold/ShortcutNonempty.hs b/source/Fold/ShortcutNonempty.hs
--- a/source/Fold/ShortcutNonempty.hs
+++ b/source/Fold/ShortcutNonempty.hs
@@ -1,6 +1,6 @@
 module Fold.ShortcutNonempty
   (
-    {- * Type -} ShortcutNonemptyFold (..),
+    {- * Type -} ShortcutNonemptyFold (..), Will (..), Vitality (..), Vitality',
 
     {- * Run -} run,
 
@@ -17,7 +17,7 @@
 
     {- * Conversion -} fold, effectfulFold, nonemptyFold, shortcutFold,
 
-    {- * Utilities -} demotivate, duplicate,
+    {- * Utilities -} motivate, demotivate, duplicate, repeatedly, premap, withVitality,
   )
   where
 
diff --git a/source/Fold/ShortcutNonempty/Type.hs b/source/Fold/ShortcutNonempty/Type.hs
--- a/source/Fold/ShortcutNonempty/Type.hs
+++ b/source/Fold/ShortcutNonempty/Type.hs
@@ -1,7 +1,7 @@
 module Fold.ShortcutNonempty.Type
   (
     ShortcutNonemptyFold (..),
-    Will (..), Vitality (..),
+    Will (..), Vitality (..), Vitality',
   )
   where
 
@@ -9,13 +9,13 @@
 import Data.Functor (Functor, fmap)
 import Data.Monoid (Monoid, mempty)
 import Data.Semigroup (Semigroup, (<>))
-import Strict (Will (..), Vitality (..))
+import Strict (Will (..), Vitality (..), Vitality')
 import Data.Void (absurd)
 
 import qualified Strict
 
-{- | Processes at least one input of type @a@, has the ability to halt
-     midway through the stream, and results in a value of type @b@ -}
+{-| Processes at least one input of type @a@, has the ability to halt
+    midway through the stream, and results in a value of type @b@ -}
 data ShortcutNonemptyFold a b = forall x y. ShortcutNonemptyFold
     { initial :: a -> Vitality x y
     , step :: y -> a -> Vitality x y
diff --git a/source/Fold/ShortcutNonempty/Utilities.hs b/source/Fold/ShortcutNonempty/Utilities.hs
--- a/source/Fold/ShortcutNonempty/Utilities.hs
+++ b/source/Fold/ShortcutNonempty/Utilities.hs
@@ -3,11 +3,22 @@
 import Fold.ShortcutNonempty.Type
 
 import Fold.Shortcut.Type (ShortcutFold (ShortcutFold))
-import Strict (willSave)
+import Strict (willSave, willBoost, getVitality')
 
 import qualified Strict
 import qualified Fold.Shortcut.Type as Empty
+import qualified Fold.Shortcut.Utilities as Empty
+import qualified Fold.Shortcut.Run as Empty (run)
+import qualified Fold.ShortcutNonempty.Conversion as Nonempty
 
+motivate :: ShortcutNonemptyFold a b -> ShortcutNonemptyFold a b
+motivate ShortcutNonemptyFold{ initial, step, extract } =
+  ShortcutNonemptyFold
+    { initial = \a -> willBoost (initial a)
+    , step = \x a -> willBoost (step x a)
+    , extract
+    }
+
 {-| Causes a shortcut fold to stop once it becomes ambivalent -}
 demotivate :: ShortcutNonemptyFold a b -> ShortcutNonemptyFold a b
 demotivate ShortcutNonemptyFold{ initial, step, extract } =
@@ -22,7 +33,7 @@
     }
 
 {-| Allows to continue feeding a fold even after passing it to a function
-that closes it -}
+    that closes it -}
 duplicate :: ShortcutNonemptyFold a b -> ShortcutNonemptyFold a (ShortcutFold a b)
 duplicate ShortcutNonemptyFold{ initial, step, extract } =
   ShortcutNonemptyFold
@@ -30,3 +41,33 @@
     , step
     , extract = \v -> ShortcutFold{ Empty.initial = v, Empty.step, Empty.extract }
     }
+
+withVitality :: ShortcutNonemptyFold a b -> ShortcutNonemptyFold a (Vitality' b)
+withVitality ShortcutNonemptyFold{ initial, step, extract } =
+  ShortcutNonemptyFold
+    { initial
+    , step
+    , extract = \v -> let x = extract v in case v of
+        Alive w _ -> Alive w x
+        Dead _ -> Dead x
+    }
+
+{-| Convert a nonempty fold for a single item (@x@) into a
+    nonempty fold for nonempty lists of items (@xs@) -}
+repeatedly :: forall x xs result.
+    (forall b. ShortcutNonemptyFold x b -> xs -> b)
+        -- ^ A witness to the fact that @xs@ is a nonempty list of @x@
+    -> ShortcutNonemptyFold x result
+    -> ShortcutNonemptyFold xs result
+repeatedly runXs foldX =
+  ShortcutNonemptyFold
+    { initial = \xs -> runXs (withVitality (duplicate foldX)) xs
+    , step = \f xs -> runXs (withVitality (Nonempty.shortcutFold (Empty.duplicate f))) xs
+    , extract = \f -> Empty.run (getVitality' f) []
+    }
+
+{-| Applies a function to each input before processing -}
+premap :: (a -> b) -> ShortcutNonemptyFold b r -> ShortcutNonemptyFold a r
+premap f ShortcutNonemptyFold{ initial, step, extract } =
+    ShortcutNonemptyFold{ initial = \a -> initial (f a),
+        step = \x a -> step x (f a), extract }
diff --git a/source/Strict.hs b/source/Strict.hs
--- a/source/Strict.hs
+++ b/source/Strict.hs
@@ -1,14 +1,15 @@
 {-# LANGUAGE StrictData #-}
 
--- | Strict data types for use as internal
--- accumulators to achieve constant space usage.
+{-| Strict data types for use as internal
+    accumulators to achieve constant space usage -}
 module Strict
   (
     {- * Maybe -} Maybe (..), lazy, strict,
     {- * Either -} Either (..), hush,
     {- * Tuples -} Tuple2 (..), Tuple3 (..),
-    {- * Shortcut -} Vitality (..), Will (..),
-        unlessDead, vitality2, willSave, isAlive, isDead,
+    {- * Shortcut -} Vitality (..), Vitality', Will (..),
+        unlessDead, vitality2, willSave, willBoost,
+        isAlive, isDead, getVitality',
   )
   where
 
@@ -69,6 +70,12 @@
     Alive Ambivalent x -> Dead (Right x)
     Alive Tenacious x -> Alive Tenacious x
 
+willBoost :: Vitality a b -> Vitality a b
+willBoost v = case v of
+    Dead x -> Dead x
+    Alive Ambivalent x -> Alive Tenacious x
+    Alive Tenacious x -> Alive Tenacious x
+
 type Vitality' a = Vitality a a
 
 vitality2 :: Vitality a1 b1 -> Vitality a2 b2
@@ -83,3 +90,8 @@
 
 isDead :: Vitality a b -> Bool
 isDead v = case v of { Alive _ _ -> False; Dead _ -> True }
+
+getVitality' :: Vitality' a -> a
+getVitality' v = case v of
+    Dead x -> x
+    Alive _ x -> x
diff --git a/test/Spec/Nonempty.hs b/test/Spec/Nonempty.hs
--- a/test/Spec/Nonempty.hs
+++ b/test/Spec/Nonempty.hs
@@ -4,10 +4,12 @@
 
 import Test.Hspec
 
+import Control.Applicative (liftA2)
 import Data.Function ((&), flip)
 import Data.List.NonEmpty (NonEmpty ((:|)))
+import Data.Maybe (Maybe (..))
 import Positive (Positive)
-import Prelude (String, Integer)
+import Prelude (String, Integer, (+), odd)
 
 import qualified Data.List as List
 import qualified Fold.Pure as Pure
@@ -48,9 +50,26 @@
 
     describe "duplicate" do
         it "lets a fold run in two phases" do
-            let a, c :: NonEmpty Integer
+            let a :: NonEmpty Integer
                 b :: [Integer]
                 a = [1..3]
                 b = [4..6]
-                c = [1..6]
-            (sum & duplicate & flip run a & flip Pure.run b) `shouldBe` (List.sum c)
+            (sum & duplicate & flip run a & flip Pure.run b)
+                `shouldBe` (List.sum a + List.sum b)
+
+    describe "repeatedly" do
+        let a, b, c :: NonEmpty Integer
+            a = [2, 4]
+            b = [10, 12, 5, 7, 8]
+            c = [4, 5, 6]
+        it "can fold a list of lists" do
+            run (repeatedly run maximum) [a, b, c] `shouldBe` 12
+        it "works in Applicative combination with another fold" do
+            let f = liftA2 (,) (repeatedly run length) length
+            run f [a, b, c] `shouldBe` (10, 3)
+        it "works in Applicative combination with another 'repeatedly'" do
+            let f = liftA2 (,) (repeatedly run (find odd)) (repeatedly run maximum)
+            run f [a, b, c] `shouldBe` (Just 5, 12)
+        it "works on an Applicative combination" do
+            let f = liftA2 (,) (find odd) maximum
+            run (repeatedly run f) [a, b, c] `shouldBe` (Just 5, 12)
diff --git a/test/Spec/Pure.hs b/test/Spec/Pure.hs
--- a/test/Spec/Pure.hs
+++ b/test/Spec/Pure.hs
@@ -4,7 +4,7 @@
 
 import Test.Hspec
 
-import Control.Applicative (pure, (<*>))
+import Control.Applicative (pure, (<*>), liftA2)
 import Data.Bool (Bool (..))
 import Data.Foldable (traverse_)
 import Data.Function (id, on, (.), (&), flip)
@@ -12,7 +12,7 @@
 import Data.Maybe (Maybe (Just, Nothing))
 import Data.Monoid (mempty)
 import Data.Semigroup (Sum (Sum))
-import Prelude ((>), String, Integer, (+), (*))
+import Prelude ((>), String, Integer, (+), (*), odd)
 
 import qualified Data.Foldable as Foldable
 import qualified Data.List as List
@@ -145,3 +145,21 @@
                 b = [4..6]
                 c = [1..6]
             (sum & duplicate & flip run a & flip run b) `shouldBe` (List.sum c)
+
+    describe "repeatedly" do
+        let a, b, c :: [Integer]
+            a = [2, 4]
+            b = [10, 12, 5, 7, 8]
+            c = [4, 5, 6]
+            abc = [a, b, c] :: [[Integer]]
+        it "can fold a list of lists" do
+            run (repeatedly run sum) abc `shouldBe` List.sum (List.concat abc)
+        it "works in Applicative combination with another fold" do
+            let f = liftA2 (,) (repeatedly run length) length
+            run f abc `shouldBe` (10, 3)
+        it "works in Applicative combination with another 'repeatedly'" do
+            let f = liftA2 (,) (repeatedly run (find odd)) (repeatedly run maximum)
+            run f abc `shouldBe` (Just 5, Just 12)
+        it "works on an Applicative combination" do
+            let f = liftA2 (,) (find odd) maximum
+            run (repeatedly run f) abc `shouldBe` (Just 5, Just 12)
diff --git a/test/Spec/Shortcut.hs b/test/Spec/Shortcut.hs
--- a/test/Spec/Shortcut.hs
+++ b/test/Spec/Shortcut.hs
@@ -4,13 +4,13 @@
 
 import Test.Hspec
 
-import Control.Applicative (pure, (<$>), (<*>))
+import Control.Applicative (pure, (<$>), (<*>), liftA2)
 import Data.Bool (Bool (..))
 import Data.Function ((&), flip)
 import Data.List ((++))
 import Data.Maybe (Maybe (Just, Nothing))
 import Data.Ord (Ord (..))
-import Prelude (Integer, undefined)
+import Prelude (Integer, undefined, odd)
 
 import qualified Data.Char as Char
 
@@ -96,3 +96,43 @@
                 b = undefined
                 f = find (>= 10)
             (f & duplicate & flip run a & flip run b) `shouldBe` Just 15
+
+    describe "repeatedly" do
+        it "can find an item in a list of lists" do
+            let a, b, c :: [Integer]
+                a = [2, 8, 6]
+                b = [12, 4, 5, 16]
+                c = [4, 18, 20]
+            run (repeatedly run (find odd)) [a, b, c]
+                `shouldBe` Just 5
+        it "preserves laziness" do
+            let a, b, c :: [Integer]
+                a = [2, 8, 6]
+                b = 12 : 4 : 5 : undefined
+                c = undefined
+            run (repeatedly run (find odd)) [a, b, c]
+                `shouldBe` Just 5
+        it "works within an Applicative combination with another 'repeatedly'" do
+            let a, b, c :: [Integer]
+                a = [2, 8, 6]
+                b = 12 : 4 : 5 : undefined
+                c = undefined
+                f = liftA2 (,) (repeatedly run (find odd)) (repeatedly run (find (> 5)))
+            run f [a, b, c]
+                `shouldBe` (Just 5, Just 8)
+        it "works on an Applicative combination of 'repeatedly's" do
+            let a, b, c :: [Integer]
+                a = [2, 8, 6]
+                b = 12 : 4 : 5 : undefined
+                c = undefined
+                f = liftA2 (,) (find odd) (find (> 5))
+            run (repeatedly run f) [a, b, c]
+                `shouldBe` (Just 5, Just 8)
+        it "works within an Applicative combination with something ambivalent" do
+            let a, b, c :: [Integer]
+                a = [2, 8, 6]
+                b = 12 : 4 : 5 : undefined
+                c = undefined
+                f = liftA2 (,) (find odd) length
+            run (repeatedly run f) [a, b, c]
+                `shouldBe` (Just 5, 6)
diff --git a/test/Spec/ShortcutNonempty.hs b/test/Spec/ShortcutNonempty.hs
--- a/test/Spec/ShortcutNonempty.hs
+++ b/test/Spec/ShortcutNonempty.hs
@@ -12,7 +12,7 @@
 import Data.Maybe (Maybe (..))
 import Data.Ord (Ord (..))
 import Positive (Positive)
-import Prelude (Integer, undefined)
+import Prelude (Integer, undefined, odd)
 
 import qualified Data.Char as Char
 import qualified Fold.Shortcut as Empty
@@ -83,3 +83,43 @@
                 b = undefined
                 f = find (>= 10)
             (f & duplicate & flip run a & flip Empty.run b) `shouldBe` Just 15
+
+    describe "repeatedly" do
+        it "can find an item in a list of lists" do
+            let a, b, c :: NonEmpty Integer
+                a = [2, 8, 6]
+                b = [12, 4, 5, 16]
+                c = [4, 18, 20]
+            run (repeatedly run (find odd)) [a, b, c]
+                `shouldBe` Just 5
+        it "preserves laziness" do
+            let a, b, c :: NonEmpty Integer
+                a = [2, 8, 6]
+                b = 12 :| 4 : 5 : undefined
+                c = undefined
+            run (repeatedly run (find odd)) [a, b, c]
+                `shouldBe` Just 5
+        it "works within an Applicative combination with another 'repeatedly'" do
+            let a, b, c :: NonEmpty Integer
+                a = [2, 8, 6]
+                b = 12 :| 4 : 5 : undefined
+                c = undefined
+                f = liftA2 (,) (repeatedly run (find odd)) (repeatedly run (find (> 5)))
+            run f [a, b, c]
+                `shouldBe` (Just 5, Just 8)
+        it "works on an Applicative combination of 'repeatedly's" do
+            let a, b, c :: NonEmpty Integer
+                a = [2, 8, 6]
+                b = 12 :| 4 : 5 : undefined
+                c = undefined
+                f = liftA2 (,) (find odd) (find (> 5))
+            run (repeatedly run f) [a, b, c]
+                `shouldBe` (Just 5, Just 8)
+        it "works within an Applicative combination with something ambivalent" do
+            let a, b, c :: NonEmpty Integer
+                a = [2, 8, 6]
+                b = 12 :| 4 : 5 : undefined
+                c = undefined
+                f = liftA2 (,) (find odd) length
+            run (repeatedly run f) [a, b, c]
+                `shouldBe` (Just 5, 6)
