diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,3 +1,13 @@
+## 0.1.0.0 (2023-02-20)
+
+Adds `ShortcutFold` and `ShortcutNonemptyFold`.
+
+The following have changed from `Fold` to `ShortcutFold`:
+`and`, `or`, `all`, `any`, `element`, `notElement`, `find`,
+`lookup`, `index`, `findIndex`, `elementIndex`, `null`.
+
+`first` has changed from `NonemptyFold` to `ShortcutNonemptyFold`.
+
 ## 0.0.1.0 (2023-02-20)
 
 Add `Fold.Nonempty.effectfulFold`; this was already available 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.0.1.0
+version: 0.1.0.0
 
 category: Streaming
 synopsis: Composable, streaming, and efficient left folds
@@ -14,7 +14,7 @@
 
 license: BSD-3-Clause
 license-file: license.txt
-copyright: 2013-2016 Gabriella Gonzalez
+copyright: 2013-2016 Gabriella Gonzalez, 2023 Mission Valley Software LLC
 
 bug-reports: https://github.com/typeclasses/gambler/issues
 
@@ -25,6 +25,7 @@
     ghc-options:
         -Wall
     default-extensions:
+        ApplicativeDo
         NoImplicitPrelude
     build-depends:
       , base ^>= 4.16 || ^>= 4.17
@@ -39,7 +40,8 @@
         Fold.Pure
         Fold.Pure.Conversion
         Fold.Pure.Examples
-        Fold.Pure.Nonempty
+        Fold.Pure.Examples.Interesting
+        Fold.Pure.Examples.Boring
         Fold.Pure.Run
         Fold.Pure.Type
         Fold.Pure.Utilities
@@ -47,8 +49,8 @@
         Fold.Effectful
         Fold.Effectful.Conversion
         Fold.Effectful.Examples
-        Fold.Effectful.Nonempty
-        Fold.Effectful.Pure
+        Fold.Effectful.Examples.Interesting
+        Fold.Effectful.Examples.Boring
         Fold.Effectful.Run
         Fold.Effectful.Type
         Fold.Effectful.Utilities
@@ -56,11 +58,30 @@
         Fold.Nonempty
         Fold.Nonempty.Conversion
         Fold.Nonempty.Examples
-        Fold.Nonempty.Pure
+        Fold.Nonempty.Examples.Interesting
+        Fold.Nonempty.Examples.Boring
         Fold.Nonempty.Run
         Fold.Nonempty.Type
         Fold.Nonempty.Utilities
 
+        Fold.Shortcut
+        Fold.Shortcut.Run
+        Fold.Shortcut.Type
+        Fold.Shortcut.Examples
+        Fold.Shortcut.Examples.Interesting
+        Fold.Shortcut.Examples.Boring
+        Fold.Shortcut.Conversion
+        Fold.Shortcut.Utilities
+
+        Fold.ShortcutNonempty
+        Fold.ShortcutNonempty.Run
+        Fold.ShortcutNonempty.Type
+        Fold.ShortcutNonempty.Examples
+        Fold.ShortcutNonempty.Examples.Interesting
+        Fold.ShortcutNonempty.Examples.Boring
+        Fold.ShortcutNonempty.Conversion
+        Fold.ShortcutNonempty.Utilities
+
     other-modules:
         Strict
 
@@ -73,6 +94,8 @@
         Spec.Pure
         Spec.Nonempty
         Spec.Effectful
+        Spec.Shortcut
+        Spec.ShortcutNonempty
     ghc-options:
         -threaded
     default-extensions:
diff --git a/license.txt b/license.txt
--- a/license.txt
+++ b/license.txt
@@ -1,4 +1,4 @@
-Copyright (c) 2013-2016 Gabriella Gonzalez
+Copyright (c) 2013-2016 Gabriella Gonzalez, 2023 Mission Valley Software LLC
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without modification,
diff --git a/readme.md b/readme.md
--- a/readme.md
+++ b/readme.md
@@ -10,7 +10,7 @@
 — *The Gambler* by Don Schlitz, popularized by Kenny Rogers
 
 
-## Intro to Fold
+## Fold
 
 The `foldl'` function in the `base` package is used when we want a strictly
 evaluated result from traversing a list.
@@ -33,7 +33,7 @@
 ```haskell
 data Fold a b = Fold
     { initial :: b
-    , step :: b -> a -> b }
+    , step    :: b -> a -> b }
 ```
 
 Or, better yet, we can use a trick to turn the datatype into a `Functor` (which
@@ -42,7 +42,7 @@
 ```haskell
 data Fold a b = forall x. Fold
     { initial :: x
-    , step :: x -> a -> x
+    , step    :: x -> a -> x
     , extract :: x -> b }
 ```
 
@@ -71,7 +71,7 @@
 dreamt of in this package.
 
 
-## Intro to NonemptyFold
+## NonemptyFold
 
 There are some kinds of folding that only work if the input it nonempty.
 Suppose, for example, we want the greatest of all the items. If there are no
@@ -81,7 +81,7 @@
 ```haskell
 data NonemptyFold a b = forall x. NonemptyFold
     { initial :: a -> x
-    , step :: x -> a -> x
+    , step    :: x -> a -> x
     , extract :: x -> b }
 ```
 
@@ -99,7 +99,7 @@
 accommodate the possibility of empty input.
 
 
-## Intro to EffectfulFold
+## EffectfulFold
 
 There is a related function in `base` that does the same thing as `foldl'` but
 in a monadic context:
@@ -127,7 +127,7 @@
 ```haskell
 data EffectfulFold m a b = forall x. EffectfulFold
     { initial :: m x
-    , step :: x -> a -> m x
+    , step    :: x -> a -> m x
     , extract :: x -> m b }
 ```
 
@@ -135,7 +135,7 @@
 `Fold.Effectful.fold`.
 
 
-## The Applicative instances
+## Applicative instances
 
 The `Fold` and `EffectfulFold` applicatives are great for computing multiple folds
 over a collection in one pass over the data. For example, suppose that you want
@@ -158,7 +158,7 @@
 With `gambler`, we can instead write:
 
 ```haskell
-import qualified Fold
+import qualified Fold.Pure as Fold
 
 sumAndLength :: Num a => [a] -> (a, Natural)
 sumAndLength = Fold.runFold $ (,) <$> Fold.sum <*> Fold.length
@@ -167,6 +167,133 @@
 This achieves the same result using constant space.
 
 
+## ShortcutFold
+
+Operations like `sum` and `length` inherently require the entirety of the input.
+But suppose, for example, we want to know whether a list contains a particular
+item. Once we find the item, we can stop looking. For situations like this, we
+have `ShortcutFold`.
+
+```haskell
+data ShortcutFold a b = forall x y. ShortcutFold
+    { initial     :: Vitality x y
+    , step        :: y -> a -> Vitality x y
+    , extractDead :: x -> b
+    , extractLive :: y -> b
+    }
+```
+
+```haskell
+data Vitality a b = Dead a | Alive Will b
+```
+
+```haskell
+data Will = Ambivalent | Tenacious
+```
+
+If `initial` or `step` returns a `Dead` result, then no further input can be fed
+into the fold. The `Will` type will be discussed below.
+
+Example of testing for the presence of a particular element:
+
+```ghci
+λ> import qualified Fold.Shortcut as Fold
+
+λ> Fold.run (Fold.element 'a') "back"
+True
+
+λ> Fold.run (Fold.element 'a') "front"
+False
+```
+
+By running a shortcut fold over a partially-defined input list, we can verify
+that evaluation does indeed halt once the element is found:
+
+```haskell
+λ> Fold.run (Fold.element 'a') ("ba" ++ undefined)
+True
+```
+
+## ShortcutNonemptyFold
+
+The non-empty variant of `ShortcutFold` is `ShortcutNonemptyFold`.
+
+```haskell
+data ShortcutNonemptyFold a b = forall x y. ShortcutNonemptyFold
+    { initial     :: a -> Vitality x y
+    , step        :: y -> a -> Vitality x y
+    , extractDead :: x -> b
+    , extractLive :: y -> b
+    }
+```
+
+Like `NonemptyFold`, the only thing we've changed here is to add an `a`
+parameter to the `initial` field.
+
+
+## Shortcutting Applicative instances
+
+Just like `Fold`, `ShortcutFold` can be combined in an applicative manner and
+the input is traversed in a single pass.
+
+```haskell
+λ> import qualified Fold.Shortcut as Fold
+
+λ> Fold.run ((,) <$> Fold.index 4 <*> Fold.index 2) "abcdef"
+(Just 'e',Just 'c')
+```
+
+With an applicative composition, traversal continues as long as any of the
+constituent parts is alive and still expecting more input. In the example above,
+`index 2` becomes dead after the third character (`'c'`), but the composition
+stays alive until the fifth character (`'e'`) results in the completion of
+`index 4`.
+
+A fold indicates that it is finished by returning `Dead` as its `Vitality`. But
+there is one more subtlety: When a fold is `Alive`, it can further specify
+whether it *wants* to keep receiving more items or not. This disposition is
+called `Will`. A `Tenacious` will means that the fold wants more input; an
+`Ambivalent` will mean the fold *can* accept more input, but doesn't care. The
+difference is that tenacious folds keep larger applicative compositions alive,
+whereas ambivalent folds do not. Shortcut folds are tagged in the documentation
+as "(ambivalent)" or "(tenacious)".
+
+One example of an ambivalent shortcut fold is `length`. We see in the example
+below that the length fold keeps counting only as long as the other fold it
+is composed with still needs input.
+
+```haskell
+λ> Fold.run ((,) <$> Fold.length <*> Fold.element 'e') "abcdef"
+(5,True)
+
+λ> Fold.run ((,) <$> Fold.length <*> Fold.element 'z') "abcdef"
+(6,False)
+```
+
+Consider another example:
+
+```haskell
+λ> f1 = ((,) <$> Fold.length <*> Fold.element 'c')
+
+λ> f2 = ((,) <$> Fold.length <*> Fold.element 'e')
+
+λ> Fold.run ((,) <$> f1 <*> f2) "abcdef"
+((5,True),(5,True))
+```
+
+The example above composes four folds (two `length` folds and two `element`
+folds). Notice that both of the length folds returned 5 because they keep
+running until the entire fold stops, regardless of the way they're composed. We
+can avoid this behavior with the `demotivate` utility, which stops a fold from
+being so eager. A demotivated fold will stop receiving input when all of its
+components are either dead or ambivalent.
+
+```haskell
+λ> Fold.run ((,) <$> Fold.demotivate f1 <*> Fold.demotivate f2) "abcdef"
+((3,True),(5,True))
+```
+
+
 ## Quick start
 
 To get quickly playing around with `gambler`, launch GHCi using `cabal`:
@@ -175,29 +302,36 @@
 cabal repl --build-depends gambler
 ```
 
-The example from the previous section can be run as follows:
+Import the module corresponding to one of the varieties of fold:
 
 ```haskell
-λ> import qualified Fold
+λ> import qualified Fold.Pure as Fold
 ```
 
+And enjoy.
+
 ```haskell
 λ> Fold.runFold ((,) <$> Fold.sum <*> Fold.length) [1..1000000]
 (500000500000,1000000)
 ```
 
 
-## Related packages
+## Authors
 
-This `gambler` package is mostly a copy of [foldl], with some features removed
-to minimize its dependency set. What remains in `gambler` is essentially the
-same as what can be found in `foldl` version `1.4.13`, subject only to
-reorganization, renaming, and minor modifications.
+This package began as mostly a copy of [foldl], with some features removed to
+minimize its dependency set. What remained in `gambler-0.0` was essentially
+the same as what could be found in `foldl-1.4.13`, subject only to
+reorganization, renaming, and minor modifications. The `Fold`, `EffectfulFold`,
+and `NonemptyFold` types are the work of Gabriella Gonzalez.
 
-  [foldl]: https://hackage.haskell.org/package/foldl
+`ShortcutFold` and `ShortcutNonemptyFold` were added by Mission Valley Software
+in `gambler-0.1`.
 
 
 ## Future plans
 
 Once the `Foldable1` class has been added to `base`, the type of
 `Fold.Nonempty.run` may be generalized to accommodate it.
+
+
+  [foldl]: https://hackage.haskell.org/package/foldl
diff --git a/source/Fold.hs b/source/Fold.hs
--- a/source/Fold.hs
+++ b/source/Fold.hs
@@ -1,7 +1,8 @@
 module Fold
   (
     {- * Fold types -} Fold (Fold), NonemptyFold (NonemptyFold),
-            EffectfulFold (EffectfulFold),
+            EffectfulFold (EffectfulFold), ShortcutFold (ShortcutFold),
+            ShortcutNonemptyFold (ShortcutNonemptyFold), Vitality (..), Will (..),
     {- * Running -} runFold, runNonemptyFold, runEffectfulFold,
     {- * Search -} element, notElement, find, lookup,
     {- * Arithmetic folds -} sum, product, mean, variance, standardDeviation,
@@ -22,10 +23,14 @@
 import Fold.Effectful.Type
 import Fold.Nonempty.Type
 import Fold.Pure.Type
+import Fold.Shortcut.Type
+import Fold.ShortcutNonempty.Type
 
-import Fold.Effectful.Examples
-import Fold.Nonempty.Examples hiding (list, reverseList)
-import Fold.Pure.Examples
+import Fold.Effectful.Examples.Interesting
+import Fold.Nonempty.Examples.Interesting hiding (list, reverseList)
+import Fold.Pure.Examples.Interesting
+import Fold.Shortcut.Examples.Interesting
+import Fold.ShortcutNonempty.Examples.Interesting
 
 import Fold.Effectful.Utilities
 
diff --git a/source/Fold/Effectful.hs b/source/Fold/Effectful.hs
--- a/source/Fold/Effectful.hs
+++ b/source/Fold/Effectful.hs
@@ -5,21 +5,17 @@
     {- * Run -} run,
 
     {- * Examples -}
-    {- ** General -} effect, effectMonoid,
-    {- ** Pure -}
-    {- *** Monoid -} monoid,
-    {- *** Length -} null, length,
-    {- *** Boolean -} and, or, all, any,
-    {- *** Numeric -} sum, product, mean, variance, standardDeviation,
-    {- *** Search -} element, notElement, find, lookup,
-    {- *** Index -} index, findIndex, elementIndex,
-    {- *** List -} list, reverseList,
-    {- ** Nonempty -}
-    {- *** General -} magma, semigroup,
-    {- *** Endpoints -} first, last,
-    {- *** Extrema -} maximum, minimum, maximumBy, minimumBy,
+    {- ** General -} effect, effectMonoid, magma, semigroup, monoid,
+    {- ** Endpoints -} first, last,
+    {- ** Extrema -} maximum, minimum, maximumBy, minimumBy,
+    {- ** Length -} null, length,
+    {- ** Boolean -} and, or, all, any,
+    {- ** Numeric -} sum, product, mean, variance, standardDeviation,
+    {- ** Search -} element, notElement, find, lookup,
+    {- ** Index -} index, findIndex, elementIndex,
+    {- ** List -} list, reverseList,
 
-    {- * Conversion -} fold, nonemptyFold,
+    {- * Conversion -} fold, nonemptyFold, shortcutFold, shortcutNonemptyFold,
 
     {- * Utilities -} hoist, duplicate, premap, prefilter, drop,
   )
@@ -27,8 +23,6 @@
 
 import Fold.Effectful.Conversion
 import Fold.Effectful.Examples
-import Fold.Effectful.Nonempty
-import Fold.Effectful.Pure
 import Fold.Effectful.Run
 import Fold.Effectful.Type
 import Fold.Effectful.Utilities
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
@@ -6,6 +6,8 @@
 import Control.Monad (Monad)
 import Data.Maybe (Maybe)
 import Fold.Nonempty.Type (NonemptyFold)
+import Fold.Shortcut.Type (ShortcutFold)
+import Fold.ShortcutNonempty.Type (ShortcutNonemptyFold)
 
 import qualified Control.Applicative as Applicative
 import qualified Fold.Pure.Conversion as Pure
@@ -23,3 +25,9 @@
 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)
+
+shortcutFold :: Monad m =>  ShortcutFold a b -> EffectfulFold m a b
+shortcutFold x = fold (Pure.shortcutFold x)
+
+shortcutNonemptyFold :: Monad m => ShortcutNonemptyFold a b -> EffectfulFold m a (Maybe b)
+shortcutNonemptyFold x = fold (Pure.shortcutNonemptyFold x)
diff --git a/source/Fold/Effectful/Examples.hs b/source/Fold/Effectful/Examples.hs
--- a/source/Fold/Effectful/Examples.hs
+++ b/source/Fold/Effectful/Examples.hs
@@ -1,25 +1,16 @@
--- | Some interesting examples of effectful folds
-module Fold.Effectful.Examples where
-
-import Fold.Effectful.Type
-
-import Control.Monad (Monad)
-import Data.Functor (void)
-import Data.Monoid (Monoid, mempty)
-import Data.Semigroup ((<>))
-import Prelude (($!))
-
-import qualified Control.Applicative as Applicative
-
-{-| Performs an action for each input, discarding the result -}
-effect :: Monad m => (a -> m b) -> EffectfulFold m a ()
-effect f = effectMonoid (\a -> void (f a))
+module Fold.Effectful.Examples
+  (
+    {- * General -} effect, effectMonoid, magma, semigroup, monoid,
+    {- * Endpoints -} first, last,
+    {- * Extrema -} maximum, minimum, maximumBy, minimumBy,
+    {- * Length -} null, length,
+    {- * Boolean -} and, or, all, any,
+    {- * Numeric -} sum, product, mean, variance, standardDeviation,
+    {- * Search -} element, notElement, find, lookup,
+    {- * Index -} index, findIndex, elementIndex,
+    {- * List -} list, reverseList,
+  )
+  where
 
-{-| Performs an action for each input, monoidally combining the results
-from all the actions. -}
-effectMonoid ::  (Monoid w, Monad m) => (a -> m w) -> EffectfulFold m a w
-effectMonoid act = EffectfulFold
-    { initial = Applicative.pure mempty
-    , step = \m a -> do{ m' <- act a; Applicative.pure $! (<>) m m' }
-    , extract = Applicative.pure
-    }
+import Fold.Effectful.Examples.Interesting
+import Fold.Effectful.Examples.Boring
diff --git a/source/Fold/Effectful/Examples/Boring.hs b/source/Fold/Effectful/Examples/Boring.hs
new file mode 100644
--- /dev/null
+++ b/source/Fold/Effectful/Examples/Boring.hs
@@ -0,0 +1,149 @@
+-- | Folds of other types trivially lifted into 'EffectfulFold'
+module Fold.Effectful.Examples.Boring
+  (
+    {- * Monoid -} monoid,
+    {- * Length -} null, length,
+    {- * Boolean -} and, or, all, any,
+    {- * Numeric -} sum, product, mean, variance, standardDeviation,
+    {- * Search -} element, notElement, find, lookup,
+    {- * Index -} index, findIndex, elementIndex,
+    {- * List -} list, reverseList,
+    {- * General -} magma, semigroup,
+    {- * Endpoints -} first, last,
+    {- * Extrema -} maximum, minimum, maximumBy, minimumBy,
+  )
+  where
+
+import Control.Monad (Monad)
+import Data.Maybe (Maybe)
+import Data.Ord (Ord, Ordering)
+import Data.Semigroup (Semigroup)
+import Fold.Effectful.Type (EffectfulFold)
+import Data.Bool (Bool)
+import Data.Eq (Eq)
+import Data.Monoid (Monoid)
+import Numeric.Natural (Natural)
+import Prelude (Floating, Fractional, Num)
+
+import qualified Fold.Pure.Examples.Interesting as Pure
+import qualified Fold.Nonempty.Examples.Interesting as Nonempty
+import qualified Fold.Shortcut.Examples.Interesting as Shortcut
+import qualified Fold.ShortcutNonempty.Examples.Interesting as ShortcutNonempty
+import qualified Fold.Effectful.Conversion as Convert
+
+{-| Start with the first input, append each new input on the right
+with the given function -}
+magma :: (a -> a -> a) -> Monad m => EffectfulFold m a (Maybe a)
+magma step = Convert.nonemptyFold (Nonempty.magma step)
+
+{-| Append each new input on the right with ('<>') -}
+semigroup :: Semigroup a => Monad m => EffectfulFold m a (Maybe a)
+semigroup = Convert.nonemptyFold Nonempty.semigroup
+
+{-| The first input -}
+first :: Monad m => EffectfulFold m a (Maybe a)
+first = Convert.shortcutNonemptyFold ShortcutNonempty.first
+
+{-| The last input -}
+last :: Monad m => EffectfulFold m a (Maybe a)
+last = Convert.nonemptyFold Nonempty.last
+
+{-| The greatest input -}
+maximum :: Ord a => Monad m => EffectfulFold m a (Maybe a)
+maximum = Convert.nonemptyFold Nonempty.maximum
+
+{-| The greatest input with respect to the given comparison function -}
+maximumBy :: (a -> a -> Ordering) -> Monad m => EffectfulFold m a (Maybe a)
+maximumBy cmp = Convert.nonemptyFold (Nonempty.maximumBy cmp)
+
+{-| The least input -}
+minimum :: Ord a => Monad m => EffectfulFold m a (Maybe a)
+minimum = Convert.nonemptyFold Nonempty.minimum
+
+{-| The least input with respect to the given comparison function -}
+minimumBy :: (a -> a -> Ordering) -> Monad m => EffectfulFold m a (Maybe a)
+minimumBy cmp = Convert.nonemptyFold (Nonempty.minimumBy cmp)
+
+{-| Start with 'mempty', append each input on the right with ('<>') -}
+monoid :: Monoid a => Monad m => EffectfulFold m a a
+monoid = Convert.fold Pure.monoid
+
+{-| 'True' if the input contains no inputs -}
+null :: Monad m => EffectfulFold m a Bool
+null = Convert.shortcutFold Shortcut.null
+
+{-| The number of inputs -}
+length :: Monad m => EffectfulFold m a Natural
+length = Convert.fold Pure.length
+
+{-| 'True' if all inputs are 'True' -}
+and :: Monad m => EffectfulFold m Bool Bool
+and = Convert.shortcutFold Shortcut.and
+
+{-| 'True' if any input is 'True' -}
+or :: Monad m => EffectfulFold m Bool Bool
+or = Convert.shortcutFold Shortcut.or
+
+{-| 'True' if all inputs satisfy the predicate -}
+all :: Monad m => (a -> Bool) -> EffectfulFold m a Bool
+all predicate = Convert.shortcutFold (Shortcut.all predicate)
+
+{-| 'True' if any input satisfies the predicate -}
+any :: Monad m => (a -> Bool) -> EffectfulFold m a Bool
+any predicate = Convert.shortcutFold (Shortcut.any predicate)
+
+{-| Adds the inputs -}
+sum :: Num a => Monad m => EffectfulFold m a a
+sum = Convert.fold Pure.sum
+
+{-| Multiplies the inputs -}
+product :: Num a => Monad m => EffectfulFold m a a
+product = Convert.fold Pure.product
+
+{-| Numerically stable arithmetic mean of the inputs -}
+mean :: Fractional a => Monad m => EffectfulFold m a a
+mean = Convert.fold Pure.mean
+
+{-| Numerically stable (population) variance over the inputs -}
+variance :: Fractional a => Monad m => EffectfulFold m a a
+variance = Convert.fold Pure.variance
+
+{-| Numerically stable (population) standard deviation over the inputs -}
+standardDeviation :: Floating a => Monad m => EffectfulFold m a a
+standardDeviation = Convert.fold Pure.standardDeviation
+
+{-| 'True' if any input is equal to the given value -}
+element :: Eq a => Monad m => a -> EffectfulFold m a Bool
+element a = Convert.shortcutFold (Shortcut.element a)
+
+{-| 'False' if any input is equal to the given value -}
+notElement :: Eq a => Monad m => a -> EffectfulFold m a Bool
+notElement a = Convert.shortcutFold (Shortcut.notElement a)
+
+{-| The first input that satisfies the predicate, if any -}
+find :: Monad m => (a -> Bool) -> EffectfulFold m a (Maybe a)
+find ok = Convert.shortcutFold (Shortcut.find ok)
+
+{-| The /n/th input, where n=0 is the first input, if the index is in bounds -}
+index :: Monad m => Natural -> EffectfulFold m a (Maybe a)
+index i = Convert.shortcutFold (Shortcut.index i)
+
+{-| The index of the first input that matches the given value, if any -}
+elementIndex :: Eq a => Monad m => a -> EffectfulFold m a (Maybe Natural)
+elementIndex a = Convert.shortcutFold (Shortcut.elementIndex a)
+
+{-| The index of the first input that satisfies the predicate, if any -}
+findIndex :: Monad m => (a -> Bool) -> EffectfulFold m a (Maybe Natural)
+findIndex ok = Convert.shortcutFold (Shortcut.findIndex ok)
+
+{-| The @b@ from the first tuple where @a@ equals the given value, if any -}
+lookup :: Eq a => Monad m => a -> EffectfulFold m (a, b) (Maybe b)
+lookup a = Convert.shortcutFold (Shortcut.lookup a)
+
+{-| All the inputs -}
+list :: Monad m => EffectfulFold m a [a]
+list = Convert.fold Pure.list
+
+{-| All the inputs in reverse order -}
+reverseList :: Monad m => EffectfulFold m a [a]
+reverseList = Convert.fold Pure.reverseList
diff --git a/source/Fold/Effectful/Examples/Interesting.hs b/source/Fold/Effectful/Examples/Interesting.hs
new file mode 100644
--- /dev/null
+++ b/source/Fold/Effectful/Examples/Interesting.hs
@@ -0,0 +1,25 @@
+-- | Some interesting examples of effectful folds
+module Fold.Effectful.Examples.Interesting where
+
+import Fold.Effectful.Type
+
+import Control.Monad (Monad)
+import Data.Functor (void)
+import Data.Monoid (Monoid, mempty)
+import Data.Semigroup ((<>))
+import Prelude (($!))
+
+import qualified Control.Applicative as Applicative
+
+{-| Performs an action for each input, discarding the result -}
+effect :: Monad m => (a -> m b) -> EffectfulFold m a ()
+effect f = effectMonoid (\a -> void (f a))
+
+{-| Performs an action for each input, monoidally combining the results
+from all the actions. -}
+effectMonoid ::  (Monoid w, Monad m) => (a -> m w) -> EffectfulFold m a w
+effectMonoid act = EffectfulFold
+    { initial = Applicative.pure mempty
+    , step = \m a -> do{ m' <- act a; Applicative.pure $! (<>) m m' }
+    , extract = Applicative.pure
+    }
diff --git a/source/Fold/Effectful/Nonempty.hs b/source/Fold/Effectful/Nonempty.hs
deleted file mode 100644
--- a/source/Fold/Effectful/Nonempty.hs
+++ /dev/null
@@ -1,50 +0,0 @@
--- | Folds from "Fold.Pure.Nonempty" trivially lifted into 'EffectfulFold'
-module Fold.Effectful.Nonempty
-  (
-    {- * General -} magma, semigroup,
-    {- * Endpoints -} first, last,
-    {- * Extrema -} maximum, minimum, maximumBy, minimumBy,
-  )
-  where
-
-import Control.Monad (Monad)
-import Data.Maybe (Maybe)
-import Data.Ord (Ord, Ordering)
-import Data.Semigroup (Semigroup)
-import Fold.Effectful.Conversion (fold)
-import Fold.Effectful.Type (EffectfulFold)
-
-import qualified Fold.Pure.Nonempty as Pure
-
-{-| Start with the first input, append each new input on the right
-with the given function -}
-magma :: (a -> a -> a) -> Monad m => EffectfulFold m a (Maybe a)
-magma step = fold (Pure.magma step)
-
-{-| Append each new input on the right with ('<>') -}
-semigroup :: Semigroup a => Monad m => EffectfulFold m a (Maybe a)
-semigroup = fold Pure.semigroup
-
-{-| The first input -}
-first :: Monad m => EffectfulFold m a (Maybe a)
-first = fold Pure.first
-
-{-| The last input -}
-last :: Monad m => EffectfulFold m a (Maybe a)
-last = fold Pure.last
-
-{-| The greatest input -}
-maximum :: Ord a => Monad m => EffectfulFold m a (Maybe a)
-maximum = fold Pure.maximum
-
-{-| The greatest input with respect to the given comparison function -}
-maximumBy :: (a -> a -> Ordering) -> Monad m => EffectfulFold m a (Maybe a)
-maximumBy cmp = fold (Pure.maximumBy cmp)
-
-{-| The least input -}
-minimum :: Ord a => Monad m => EffectfulFold m a (Maybe a)
-minimum = fold Pure.minimum
-
-{-| The least input with respect to the given comparison function -}
-minimumBy :: (a -> a -> Ordering) -> Monad m => EffectfulFold m a (Maybe a)
-minimumBy cmp = fold (Pure.minimumBy cmp)
diff --git a/source/Fold/Effectful/Pure.hs b/source/Fold/Effectful/Pure.hs
deleted file mode 100644
--- a/source/Fold/Effectful/Pure.hs
+++ /dev/null
@@ -1,108 +0,0 @@
--- | Folds from "Fold.Pure.Examples" trivially lifted into 'EffectfulFold'
-module Fold.Effectful.Pure
-  (
-    {- * Monoid -} monoid,
-    {- * Length -} null, length,
-    {- * Boolean -} and, or, all, any,
-    {- * Numeric -} sum, product, mean, variance, standardDeviation,
-    {- * Search -} element, notElement, find, lookup,
-    {- * Index -} index, findIndex, elementIndex,
-    {- * List -} list, reverseList,
-  )
-  where
-
-import Control.Monad (Monad)
-import Data.Bool (Bool)
-import Data.Eq (Eq)
-import Data.Maybe (Maybe)
-import Data.Monoid (Monoid)
-import Fold.Effectful.Conversion (fold)
-import Fold.Effectful.Type (EffectfulFold)
-import Numeric.Natural (Natural)
-import Prelude (Floating, Fractional, Num)
-
-import qualified Fold.Pure.Examples as Pure
-
-{-| Start with 'mempty', append each input on the right with ('<>') -}
-monoid :: Monoid a => Monad m => EffectfulFold m a a
-monoid = fold Pure.monoid
-
-{-| 'True' if the input contains no inputs -}
-null :: Monad m => EffectfulFold m a Bool
-null = fold Pure.null
-
-{-| The number of inputs -}
-length :: Monad m => EffectfulFold m a Natural
-length = fold Pure.length
-
-{-| 'True' if all inputs are 'True' -}
-and :: Monad m => EffectfulFold m Bool Bool
-and = fold Pure.and
-
-{-| 'True' if any input is 'True' -}
-or :: Monad m => EffectfulFold m Bool Bool
-or = fold Pure.or
-
-{-| 'True' if all inputs satisfy the predicate -}
-all :: Monad m => (a -> Bool) -> EffectfulFold m a Bool
-all predicate = fold (Pure.all predicate)
-
-{-| 'True' if any input satisfies the predicate -}
-any :: Monad m => (a -> Bool) -> EffectfulFold m a Bool
-any predicate = fold (Pure.any predicate)
-
-{-| Adds the inputs -}
-sum :: Num a => Monad m => EffectfulFold m a a
-sum = fold Pure.sum
-
-{-| Multiplies the inputs -}
-product :: Num a => Monad m => EffectfulFold m a a
-product = fold Pure.product
-
-{-| Numerically stable arithmetic mean of the inputs -}
-mean :: Fractional a => Monad m => EffectfulFold m a a
-mean = fold Pure.mean
-
-{-| Numerically stable (population) variance over the inputs -}
-variance :: Fractional a => Monad m => EffectfulFold m a a
-variance = fold Pure.variance
-
-{-| Numerically stable (population) standard deviation over the inputs -}
-standardDeviation :: Floating a => Monad m => EffectfulFold m a a
-standardDeviation = fold Pure.standardDeviation
-
-{-| 'True' if any input is equal to the given value -}
-element :: Eq a => Monad m => a -> EffectfulFold m a Bool
-element a = fold (Pure.element a)
-
-{-| 'False' if any input is equal to the given value -}
-notElement :: Eq a => Monad m => a -> EffectfulFold m a Bool
-notElement a = fold (Pure.notElement a)
-
-{-| The first input that satisfies the predicate, if any -}
-find :: Monad m => (a -> Bool) -> EffectfulFold m a (Maybe a)
-find ok = fold (Pure.find ok)
-
-{-| The /n/th input, where n=0 is the first input, if the index is in bounds -}
-index :: Monad m => Natural -> EffectfulFold m a (Maybe a)
-index i = fold (Pure.index i)
-
-{-| The index of the first input that matches the given value, if any -}
-elementIndex :: Eq a => Monad m => a -> EffectfulFold m a (Maybe Natural)
-elementIndex a = fold (Pure.elementIndex a)
-
-{-| The index of the first input that satisfies the predicate, if any -}
-findIndex :: Monad m => (a -> Bool) -> EffectfulFold m a (Maybe Natural)
-findIndex ok = fold (Pure.findIndex ok)
-
-{-| The @b@ from the first tuple where @a@ equals the given value, if any -}
-lookup :: Eq a => Monad m => a -> EffectfulFold m (a, b) (Maybe b)
-lookup a = fold (Pure.lookup a)
-
-{-| All the inputs -}
-list :: Monad m => EffectfulFold m a [a]
-list = fold Pure.list
-
-{-| All the inputs in reverse order -}
-reverseList :: Monad m => EffectfulFold m a [a]
-reverseList = fold Pure.reverseList
diff --git a/source/Fold/Nonempty.hs b/source/Fold/Nonempty.hs
--- a/source/Fold/Nonempty.hs
+++ b/source/Fold/Nonempty.hs
@@ -5,19 +5,17 @@
     {- * Run -} run,
 
     {- * Examples -}
-    {- ** General -} magma, semigroup,
+    {- ** General -} magma, semigroup, monoid,
     {- ** Endpoints -} first, last,
     {- ** Extrema -} maximum, minimum, maximumBy, minimumBy,
-    {- ** Pure -}
-    {- *** Monoid -} monoid,
-    {- *** Length -} null, length,
-    {- *** Boolean -} and, or, all, any,
-    {- *** Numeric -} sum, product, mean, variance, standardDeviation,
-    {- *** Search -} element, notElement, find, lookup,
-    {- *** Index -} index, findIndex, elementIndex,
-    {- *** List -} list, reverseList,
+    {- ** Length -} length,
+    {- ** Boolean -} and, or, all, any,
+    {- ** Numeric -} sum, product, mean, variance, standardDeviation,
+    {- ** Search -} element, notElement, find, lookup,
+    {- ** Index -} index, findIndex, elementIndex,
+    {- ** List -} list, reverseList,
 
-    {- * Conversion -} fold, effectfulFold,
+    {- * Conversion -} fold, effectfulFold, shortcutFold, shortcutNonemptyFold,
 
     {- * Utilities -} duplicate, premap, nest,
   )
@@ -25,7 +23,6 @@
 
 import Fold.Nonempty.Conversion
 import Fold.Nonempty.Examples
-import Fold.Nonempty.Pure hiding (list, reverseList)
 import Fold.Nonempty.Run
 import Fold.Nonempty.Type
 import Fold.Nonempty.Utilities
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
@@ -5,11 +5,14 @@
 
 import Fold.Effectful.Type (EffectfulFold)
 import Fold.Pure.Type (Fold (Fold))
+import Fold.ShortcutNonempty.Type (ShortcutNonemptyFold (ShortcutNonemptyFold))
+import Fold.Shortcut.Type (ShortcutFold)
+import Strict (Vitality (Dead, Alive))
+import Data.Functor.Identity (Identity)
 
 import qualified Fold.Pure.Type as Fold
 import qualified Fold.Pure.Conversion as Fold.Conversion
-
-import Data.Functor.Identity (Identity)
+import qualified Fold.ShortcutNonempty.Type as ShortcutNonempty
 
 {-| Turn a regular fold that allows empty input into a fold that
 requires at least one input -}
@@ -21,3 +24,17 @@
 one input -}
 effectfulFold :: EffectfulFold Identity a b -> NonemptyFold a b
 effectfulFold x = fold (Fold.Conversion.effectfulFold x)
+
+shortcutFold :: ShortcutFold a b -> NonemptyFold a b
+shortcutFold x = fold (Fold.Conversion.shortcutFold x)
+
+shortcutNonemptyFold :: ShortcutNonemptyFold a b -> NonemptyFold a b
+shortcutNonemptyFold ShortcutNonemptyFold{ ShortcutNonempty.step,
+        ShortcutNonempty.initial, ShortcutNonempty.extractDead, ShortcutNonempty.extractLive } =
+    NonemptyFold
+      { initial = initial
+      , step = \s -> case s of { Dead _ -> \_ -> s; Alive _ x -> step x }
+      , extract = \s -> case s of
+            Dead x -> extractDead x
+            Alive _ x -> extractLive x
+      }
diff --git a/source/Fold/Nonempty/Examples.hs b/source/Fold/Nonempty/Examples.hs
--- a/source/Fold/Nonempty/Examples.hs
+++ b/source/Fold/Nonempty/Examples.hs
@@ -1,66 +1,16 @@
 module Fold.Nonempty.Examples
   (
-    {- * General -} magma, semigroup,
+    {- * General -} magma, semigroup, monoid,
     {- * Endpoints -} first, last,
     {- * Extrema -} maximum, minimum, maximumBy, minimumBy,
+    {- * Length -} length,
+    {- * Boolean -} and, or, all, any,
+    {- * Numeric -} sum, product, mean, variance, standardDeviation,
+    {- * Search -} element, notElement, find, lookup,
+    {- * Index -} index, findIndex, elementIndex,
     {- * List -} list, reverseList,
   )
   where
 
-import Fold.Nonempty.Type
-
-import Data.Function (id, const, flip, (.))
-import Data.List.NonEmpty (NonEmpty ((:|)))
-import Data.Ord (Ord, Ordering (GT), max, min)
-import Data.Semigroup (Semigroup, (<>))
-
-import qualified Strict
-
-{-| Start with the first input, append each new input on the right
-with the given function -}
-magma :: (a -> a -> a) -> NonemptyFold a a
-magma step = NonemptyFold{ initial = id, step, extract = id }
-
-{-| Append each new input on the right with ('<>') -}
-semigroup :: Semigroup a => NonemptyFold a a
-semigroup = magma (<>)
-
-{-| The first input -}
-first :: NonemptyFold a a
-first = magma const
-
-{-| The last input -}
-last :: NonemptyFold a a
-last = magma (flip const)
-
-{-| The greatest input -}
-maximum :: Ord a => NonemptyFold a a
-maximum = magma max
-
-{-| The greatest input with respect to the given comparison function -}
-maximumBy :: (a -> a -> Ordering) -> NonemptyFold a a
-maximumBy cmp = magma (\x y -> case cmp x y of { GT -> x; _ -> y })
-
-{-| The least input -}
-minimum :: Ord a => NonemptyFold a a
-minimum = magma min
-
-{-| The least input with respect to the given comparison function -}
-minimumBy :: (a -> a -> Ordering) -> NonemptyFold a a
-minimumBy cmp = magma (\x y -> case cmp x y of { GT -> y; _ -> x })
-
-{-| All the inputs -}
-list :: NonemptyFold a (NonEmpty a)
-list = NonemptyFold
-    { initial = \a -> Strict.Tuple2 a id
-    , step = \(Strict.Tuple2 a0 x) a -> Strict.Tuple2 a0 (x . (a :))
-    , extract = \(Strict.Tuple2 a0 x) -> a0 :| (x [])
-    }
-
-{-| All the inputs in reverse order -}
-reverseList :: NonemptyFold a (NonEmpty a)
-reverseList = NonemptyFold
-    { initial = (:| [])
-    , step = \(b :| x) a -> a :| b : x
-    , extract = id
-    }
+import Fold.Nonempty.Examples.Interesting
+import Fold.Nonempty.Examples.Boring hiding (list, reverseList)
diff --git a/source/Fold/Nonempty/Examples/Boring.hs b/source/Fold/Nonempty/Examples/Boring.hs
new file mode 100644
--- /dev/null
+++ b/source/Fold/Nonempty/Examples/Boring.hs
@@ -0,0 +1,110 @@
+-- | Folds of other types trivially lifted into 'NonemptyFold'
+module Fold.Nonempty.Examples.Boring
+  (
+    {- * Endpoints -} first,
+    {- * Monoid -} monoid,
+    {- * Length -} length,
+    {- * Boolean -} and, or, all, any,
+    {- * Numeric -} sum, product, mean, variance, standardDeviation,
+    {- * Search -} element, notElement, find, lookup,
+    {- * Index -} index, findIndex, elementIndex,
+    {- * List -} list, reverseList,
+  )
+  where
+
+import Data.Bool (Bool)
+import Data.Eq (Eq)
+import Data.Maybe (Maybe)
+import Data.Monoid (Monoid)
+import Fold.Nonempty.Type (NonemptyFold)
+import Numeric.Natural (Natural)
+import Prelude (Floating, Fractional, Num)
+
+import qualified Fold.Nonempty.Conversion as Convert
+import qualified Fold.Pure.Examples.Interesting as Pure
+import qualified Fold.Shortcut.Examples.Interesting as Shortcut
+import qualified Fold.ShortcutNonempty.Examples as ShortcutNonempty
+
+{-| The first input -}
+first :: NonemptyFold a a
+first = Convert.shortcutNonemptyFold ShortcutNonempty.first
+
+{-| Start with 'mempty', append each input on the right with ('<>') -}
+monoid :: Monoid a => NonemptyFold a a
+monoid = Convert.fold Pure.monoid
+
+{-| The number of inputs -}
+length :: NonemptyFold a Natural
+length = Convert.fold Pure.length
+
+{-| 'True' if all inputs are 'True' -}
+and :: NonemptyFold Bool Bool
+and = Convert.shortcutFold Shortcut.and
+
+{-| 'True' if any input is 'True' -}
+or :: NonemptyFold Bool Bool
+or = Convert.shortcutFold Shortcut.or
+
+{-| 'True' if all inputs satisfy the predicate -}
+all :: (a -> Bool) -> NonemptyFold a Bool
+all predicate = Convert.shortcutFold (Shortcut.all predicate)
+
+{-| 'True' if any input satisfies the predicate -}
+any :: (a -> Bool) -> NonemptyFold a Bool
+any predicate = Convert.shortcutFold (Shortcut.any predicate)
+
+{-| Adds the inputs -}
+sum :: Num a => NonemptyFold a a
+sum = Convert.fold Pure.sum
+
+{-| Multiplies the inputs -}
+product :: Num a => NonemptyFold a a
+product = Convert.fold Pure.product
+
+{-| Numerically stable arithmetic mean of the inputs -}
+mean :: Fractional a => NonemptyFold a a
+mean = Convert.fold Pure.mean
+
+{-| Numerically stable (population) variance over the inputs -}
+variance :: Fractional a => NonemptyFold a a
+variance = Convert.fold Pure.variance
+
+{-| Numerically stable (population) standard deviation over the inputs -}
+standardDeviation :: Floating a => NonemptyFold a a
+standardDeviation = Convert.fold Pure.standardDeviation
+
+{-| 'True' if any input is equal to the given value -}
+element :: Eq a => a -> NonemptyFold a Bool
+element a = Convert.shortcutFold (Shortcut.element a)
+
+{-| 'False' if any input is equal to the given value -}
+notElement :: Eq a => a -> NonemptyFold a Bool
+notElement a = Convert.shortcutFold (Shortcut.notElement a)
+
+{-| The first input that satisfies the predicate, if any -}
+find :: (a -> Bool) -> NonemptyFold a (Maybe a)
+find ok = Convert.shortcutFold (Shortcut.find ok)
+
+{-| The /n/th input, where n=0 is the first input, if the index is in bounds -}
+index :: Natural -> NonemptyFold a (Maybe a)
+index i = Convert.shortcutFold (Shortcut.index i)
+
+{-| The index of the first input that matches the given value, if any -}
+elementIndex :: Eq a => a -> NonemptyFold a (Maybe Natural)
+elementIndex a = Convert.shortcutFold (Shortcut.elementIndex a)
+
+{-| The index of the first input that satisfies the predicate, if any -}
+findIndex :: (a -> Bool) -> NonemptyFold a (Maybe Natural)
+findIndex ok = Convert.shortcutFold (Shortcut.findIndex ok)
+
+{-| The @b@ from the first tuple where @a@ equals the given value, if any -}
+lookup :: Eq a => a -> NonemptyFold (a, b) (Maybe b)
+lookup a = Convert.shortcutFold (Shortcut.lookup a)
+
+{-| All the inputs -}
+list :: NonemptyFold a [a]
+list = Convert.fold Pure.list
+
+{-| All the inputs in reverse order -}
+reverseList :: NonemptyFold a [a]
+reverseList = Convert.fold Pure.reverseList
diff --git a/source/Fold/Nonempty/Examples/Interesting.hs b/source/Fold/Nonempty/Examples/Interesting.hs
new file mode 100644
--- /dev/null
+++ b/source/Fold/Nonempty/Examples/Interesting.hs
@@ -0,0 +1,62 @@
+module Fold.Nonempty.Examples.Interesting
+  (
+    {- * General -} magma, semigroup,
+    {- * Endpoints -} last,
+    {- * Extrema -} maximum, minimum, maximumBy, minimumBy,
+    {- * List -} list, reverseList,
+  )
+  where
+
+import Fold.Nonempty.Type
+
+import Data.Function (id, const, flip, (.))
+import Data.List.NonEmpty (NonEmpty ((:|)))
+import Data.Ord (Ord, Ordering (GT), max, min)
+import Data.Semigroup (Semigroup, (<>))
+
+import qualified Strict
+
+{-| Start with the first input, append each new input on the right
+with the given function -}
+magma :: (a -> a -> a) -> NonemptyFold a a
+magma step = NonemptyFold{ initial = id, step, extract = id }
+
+{-| Append each new input on the right with ('<>') -}
+semigroup :: Semigroup a => NonemptyFold a a
+semigroup = magma (<>)
+
+{-| The last input -}
+last :: NonemptyFold a a
+last = magma (flip const)
+
+{-| The greatest input -}
+maximum :: Ord a => NonemptyFold a a
+maximum = magma max
+
+{-| The greatest input with respect to the given comparison function -}
+maximumBy :: (a -> a -> Ordering) -> NonemptyFold a a
+maximumBy cmp = magma (\x y -> case cmp x y of { GT -> x; _ -> y })
+
+{-| The least input -}
+minimum :: Ord a => NonemptyFold a a
+minimum = magma min
+
+{-| The least input with respect to the given comparison function -}
+minimumBy :: (a -> a -> Ordering) -> NonemptyFold a a
+minimumBy cmp = magma (\x y -> case cmp x y of { GT -> y; _ -> x })
+
+{-| All the inputs -}
+list :: NonemptyFold a (NonEmpty a)
+list = NonemptyFold
+    { initial = \a -> Strict.Tuple2 a id
+    , step = \(Strict.Tuple2 a0 x) a -> Strict.Tuple2 a0 (x . (a :))
+    , extract = \(Strict.Tuple2 a0 x) -> a0 :| (x [])
+    }
+
+{-| All the inputs in reverse order -}
+reverseList :: NonemptyFold a (NonEmpty a)
+reverseList = NonemptyFold
+    { initial = (:| [])
+    , step = \(b :| x) a -> a :| b : x
+    , extract = id
+    }
diff --git a/source/Fold/Nonempty/Pure.hs b/source/Fold/Nonempty/Pure.hs
deleted file mode 100644
--- a/source/Fold/Nonempty/Pure.hs
+++ /dev/null
@@ -1,107 +0,0 @@
--- | Folds from "Fold.Pure.Examples" trivially lifted into 'NonemptyFold'
-module Fold.Nonempty.Pure
-  (
-    {- * Monoid -} monoid,
-    {- * Length -} null, length,
-    {- * Boolean -} and, or, all, any,
-    {- * Numeric -} sum, product, mean, variance, standardDeviation,
-    {- * Search -} element, notElement, find, lookup,
-    {- * Index -} index, findIndex, elementIndex,
-    {- * List -} list, reverseList,
-  )
-  where
-
-import qualified Fold.Pure.Examples as Pure
-
-import Data.Bool (Bool)
-import Data.Eq (Eq)
-import Data.Maybe (Maybe)
-import Data.Monoid (Monoid)
-import Fold.Nonempty.Conversion (fold)
-import Fold.Nonempty.Type (NonemptyFold)
-import Numeric.Natural (Natural)
-import Prelude (Floating, Fractional, Num)
-
-{-| Start with 'mempty', append each input on the right with ('<>') -}
-monoid :: Monoid a => NonemptyFold a a
-monoid = fold Pure.monoid
-
-{-| 'True' if the input contains no inputs -}
-null :: NonemptyFold a Bool
-null = fold Pure.null
-
-{-| The number of inputs -}
-length :: NonemptyFold a Natural
-length = fold Pure.length
-
-{-| 'True' if all inputs are 'True' -}
-and :: NonemptyFold Bool Bool
-and = fold Pure.and
-
-{-| 'True' if any input is 'True' -}
-or :: NonemptyFold Bool Bool
-or = fold Pure.or
-
-{-| 'True' if all inputs satisfy the predicate -}
-all :: (a -> Bool) -> NonemptyFold a Bool
-all predicate = fold (Pure.all predicate)
-
-{-| 'True' if any input satisfies the predicate -}
-any :: (a -> Bool) -> NonemptyFold a Bool
-any predicate = fold (Pure.any predicate)
-
-{-| Adds the inputs -}
-sum :: Num a => NonemptyFold a a
-sum = fold Pure.sum
-
-{-| Multiplies the inputs -}
-product :: Num a => NonemptyFold a a
-product = fold Pure.product
-
-{-| Numerically stable arithmetic mean of the inputs -}
-mean :: Fractional a => NonemptyFold a a
-mean = fold Pure.mean
-
-{-| Numerically stable (population) variance over the inputs -}
-variance :: Fractional a => NonemptyFold a a
-variance = fold Pure.variance
-
-{-| Numerically stable (population) standard deviation over the inputs -}
-standardDeviation :: Floating a => NonemptyFold a a
-standardDeviation = fold Pure.standardDeviation
-
-{-| 'True' if any input is equal to the given value -}
-element :: Eq a => a -> NonemptyFold a Bool
-element a = fold (Pure.element a)
-
-{-| 'False' if any input is equal to the given value -}
-notElement :: Eq a => a -> NonemptyFold a Bool
-notElement a = fold (Pure.notElement a)
-
-{-| The first input that satisfies the predicate, if any -}
-find :: (a -> Bool) -> NonemptyFold a (Maybe a)
-find ok = fold (Pure.find ok)
-
-{-| The /n/th input, where n=0 is the first input, if the index is in bounds -}
-index :: Natural -> NonemptyFold a (Maybe a)
-index i = fold (Pure.index i)
-
-{-| The index of the first input that matches the given value, if any -}
-elementIndex :: Eq a => a -> NonemptyFold a (Maybe Natural)
-elementIndex a = fold (Pure.elementIndex a)
-
-{-| The index of the first input that satisfies the predicate, if any -}
-findIndex :: (a -> Bool) -> NonemptyFold a (Maybe Natural)
-findIndex ok = fold (Pure.findIndex ok)
-
-{-| The @b@ from the first tuple where @a@ equals the given value, if any -}
-lookup :: Eq a => a -> NonemptyFold (a, b) (Maybe b)
-lookup a = fold (Pure.lookup a)
-
-{-| All the inputs -}
-list :: NonemptyFold a [a]
-list = fold Pure.list
-
-{-| All the inputs in reverse order -}
-reverseList :: NonemptyFold a [a]
-reverseList = fold Pure.reverseList
diff --git a/source/Fold/Pure.hs b/source/Fold/Pure.hs
--- a/source/Fold/Pure.hs
+++ b/source/Fold/Pure.hs
@@ -5,19 +5,17 @@
     {- * Run -} run, scan, prescan, postscan,
 
     {- * Examples -}
-    {- ** Monoid -} monoid,
+    {- ** General -} magma, semigroup, monoid,
+    {- ** Endpoints -} first, last,
+    {- ** Extrema -} maximum, minimum, maximumBy, minimumBy,
     {- ** Length -} null, length,
     {- ** Boolean -} and, or, all, any,
     {- ** Numeric -} sum, product, mean, variance, standardDeviation,
     {- ** Search -} element, notElement, find, lookup,
     {- ** Index -} index, findIndex, elementIndex,
     {- ** List -} list, reverseList,
-    {- ** Nonempty -}
-    {- *** General -} magma, semigroup,
-    {- *** Endpoints -} first, last,
-    {- *** Extrema -} maximum, minimum, maximumBy, minimumBy,
 
-    {- * Conversion -} effectfulFold, nonemptyFold,
+    {- * Conversion -} effectfulFold, nonemptyFold, shortcutFold, shortcutNonemptyFold,
 
     {- * Utilities -} duplicate, premap, prefilter, predropWhile, drop, nest,
   )
@@ -25,7 +23,6 @@
 
 import Fold.Pure.Conversion
 import Fold.Pure.Examples
-import Fold.Pure.Nonempty
 import Fold.Pure.Run
 import Fold.Pure.Type
 import Fold.Pure.Utilities
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
@@ -4,14 +4,19 @@
 import Fold.Pure.Type
 
 import Data.Function (($))
-import Data.Functor ((<$>))
+import Data.Functor ((<$>), (<&>))
 import Data.Functor.Identity (Identity, runIdentity)
 import Data.Maybe (Maybe)
 import Fold.Effectful.Type (EffectfulFold (EffectfulFold))
 import Fold.Nonempty.Type (NonemptyFold (NonemptyFold))
+import Fold.Shortcut.Type (ShortcutFold (ShortcutFold))
+import Fold.ShortcutNonempty.Type (ShortcutNonemptyFold (ShortcutNonemptyFold))
+import Strict (Vitality (Dead, Alive))
 
 import qualified Fold.Effectful.Type as Effectful
 import qualified Fold.Nonempty.Type as Nonempty
+import qualified Fold.ShortcutNonempty.Type as ShortcutNonempty
+import qualified Fold.Shortcut.Type as Shortcut
 import qualified Strict
 
 {-| Turn an effectful fold into a pure fold -}
@@ -35,4 +40,29 @@
             Strict.Nothing -> initial a
             Strict.Just x -> step x a
       , extract = \xm -> extract <$> Strict.lazy xm
+      }
+
+shortcutFold :: ShortcutFold a b -> Fold a b
+shortcutFold ShortcutFold{
+        Shortcut.initial, Shortcut.step, Shortcut.extractLive, Shortcut.extractDead } =
+    Fold
+      { initial = initial
+      , step = \s -> case s of { Dead _ -> \_ -> s; Alive _ x -> step x }
+      , extract = \s -> case s of
+            Dead    x -> extractDead x
+            Alive _ x -> extractLive x
+      }
+
+shortcutNonemptyFold :: ShortcutNonemptyFold a b -> Fold a (Maybe b)
+shortcutNonemptyFold ShortcutNonemptyFold{ ShortcutNonempty.initial,
+        ShortcutNonempty.step, ShortcutNonempty.extractLive, ShortcutNonempty.extractDead } =
+    Fold
+      { initial = Strict.Nothing
+      , step = \xm a -> case xm of
+            Strict.Nothing -> Strict.Just (initial a)
+            Strict.Just (Alive _ x) -> Strict.Just (step x a)
+            Strict.Just (Dead    _) -> xm
+      , extract = \xm -> Strict.lazy xm <&> \s -> case s of
+            Dead    x -> extractDead x
+            Alive _ x -> extractLive x
       }
diff --git a/source/Fold/Pure/Examples.hs b/source/Fold/Pure/Examples.hs
--- a/source/Fold/Pure/Examples.hs
+++ b/source/Fold/Pure/Examples.hs
@@ -1,6 +1,8 @@
 module Fold.Pure.Examples
   (
-    {- * Monoid -} monoid,
+    {- * General -} magma, semigroup, monoid,
+    {- * Endpoints -} first, last,
+    {- * Extrema -} maximum, minimum, maximumBy, minimumBy,
     {- * Length -} null, length,
     {- * Boolean -} and, or, all, any,
     {- * Numeric -} sum, product, mean, variance, standardDeviation,
@@ -10,143 +12,5 @@
   )
   where
 
-import Fold.Pure.Type
-
-import Data.Bool (Bool (False, True), (&&), (||))
-import Data.Eq (Eq, (/=), (==))
-import Data.Function (id, ($), (.))
-import Data.Functor ((<$>))
-import Data.Maybe (Maybe)
-import Data.Monoid (Monoid, mempty)
-import Data.Semigroup ((<>))
-import Numeric.Natural (Natural)
-import Prelude (Floating, Fractional, Num, sqrt, (*), (+), (-), (/))
-
-import qualified Strict
-
-{-| Start with 'mempty', append each input on the right with ('<>') -}
-monoid :: Monoid a => Fold a a
-monoid = Fold{ initial = mempty, step = (<>), extract = id }
-
-{-| 'True' if the input contains no inputs -}
-null :: Fold a Bool
-null = Fold{ initial = True, step = \_ _ -> False, extract = id }
-
-{-| The number of inputs -}
-length :: Fold a Natural
-length = Fold{ initial = 0, step = \n _ -> n + 1, extract = id }
-
-{-| 'True' if all inputs are 'True' -}
-and :: Fold Bool Bool
-and = Fold{ initial = True, step = (&&), extract = id }
-
-{-| 'True' if any input is 'True' -}
-or :: Fold Bool Bool
-or = Fold{ initial = False, step = (||), extract = id }
-
-{-| 'True' if all inputs satisfy the predicate -}
-all :: (a -> Bool) -> Fold a Bool
-all predicate =
-    Fold{ initial = True, step = \x a -> x && predicate a, extract = id }
-
-{-| 'True' if any input satisfies the predicate -}
-any :: (a -> Bool) -> Fold a Bool
-any predicate =
-    Fold{ initial = False, step = \x a -> x || predicate a, extract = id }
-
-{-| Adds the inputs -}
-sum :: Num a => Fold a a
-sum = Fold{ initial = 0, step = (+), extract = id }
-
-{-| Multiplies the inputs -}
-product :: Num a => Fold a a
-product = Fold{ initial = 1, step = (*), extract = id }
-
-{-| Numerically stable arithmetic mean of the inputs -}
-mean :: Fractional a => Fold a a
-mean = Fold
-    { initial = Strict.Tuple2 0 0
-    , step = \(Strict.Tuple2 x n) y ->
-        let n' = n + 1 in
-        Strict.Tuple2 (x + (y - x) / n') n'
-    , extract = \(Strict.Tuple2 x _) -> x
-    }
-
-{-| Numerically stable (population) variance over the inputs -}
-variance :: Fractional a => Fold a a
-variance = Fold
-    { initial = Strict.Tuple3 0 0 0
-    , step = \(Strict.Tuple3 n mean_ m2) x ->
-        let
-          n'     = n + 1
-          mean'  = (n * mean_ + x) / (n + 1)
-          delta  = x - mean_
-          m2'    = m2 + delta * delta * n / (n + 1)
-        in
-          Strict.Tuple3 n' mean' m2'
-    , extract = \(Strict.Tuple3 n _ m2) -> m2 / n
-    }
-
-{-| Numerically stable (population) standard deviation over the inputs -}
-standardDeviation :: Floating a => Fold a a
-standardDeviation = sqrt <$> variance
-
-{-| 'True' if any input is equal to the given value -}
-element :: Eq a => a -> Fold a Bool
-element a = any (a ==)
-
-{-| 'False' if any input is equal to the given value -}
-notElement :: Eq a => a -> Fold a Bool
-notElement a = all (a /=)
-
-{-| The first input that satisfies the predicate, if any -}
-find :: (a -> Bool) -> Fold a (Maybe a)
-find ok = Fold
-    { initial = Strict.Nothing
-    , step = \x a -> case x of
-        Strict.Nothing -> if ok a then Strict.Just a else Strict.Nothing
-        _ -> x
-    , extract = Strict.lazy
-    }
-
-{-| The /n/th input, where n=0 is the first input, if the index is in bounds -}
-index :: Natural -> Fold a (Maybe a)
-index i = Fold
-    { initial = Strict.Left 0
-    , step = \x a -> case x of
-        Strict.Left j -> if i == j then Strict.Right a else Strict.Left (j + 1)
-        _ -> x
-    , extract = Strict.hush
-    }
-
-{-| The index of the first input that matches the given value, if any -}
-elementIndex :: Eq a => a -> Fold a (Maybe Natural)
-elementIndex a = findIndex (a ==)
-
-{-| The index of the first input that satisfies the predicate, if any -}
-findIndex :: (a -> Bool) -> Fold a (Maybe Natural)
-findIndex ok = Fold
-    { initial = Strict.Left 0
-    , step = \x a -> case x of
-        Strict.Left i -> if ok a then Strict.Right i else Strict.Left (i + 1)
-        _ -> x
-    , extract = Strict.hush
-    }
-
-{-| The @b@ from the first tuple where @a@ equals the given value, if any -}
-lookup :: Eq a => a -> Fold (a, b) (Maybe b)
-lookup a0 = Fold
-    { initial = Strict.Nothing
-    , step = \x (a, b) -> case x of
-        Strict.Nothing -> if a == a0 then Strict.Just b else Strict.Nothing
-        _ -> x
-    , extract = Strict.lazy
-    }
-
-{-| All the inputs -}
-list :: Fold a [a]
-list = Fold{ initial = id, step = \x a -> x . (a :), extract = ($ []) }
-
-{-| All the inputs in reverse order -}
-reverseList :: Fold a [a]
-reverseList = Fold{ initial = [], step = \x a -> a : x, extract = id }
+import Fold.Pure.Examples.Interesting
+import Fold.Pure.Examples.Boring
diff --git a/source/Fold/Pure/Examples/Boring.hs b/source/Fold/Pure/Examples/Boring.hs
new file mode 100644
--- /dev/null
+++ b/source/Fold/Pure/Examples/Boring.hs
@@ -0,0 +1,106 @@
+-- | Folds of other types trivially lifted into 'Fold'
+module Fold.Pure.Examples.Boring
+  (
+    {- * Length -} null,
+    {- * General -} magma, semigroup,
+    {- * Endpoints -} first, last,
+    {- * Extrema -} maximum, minimum, maximumBy, minimumBy,
+    {- * Boolean -} and, or, all, any,
+    {- * Search -} element, notElement, find, lookup,
+    {- * Index -} index, findIndex, elementIndex,
+  )
+  where
+
+import Data.Maybe (Maybe)
+import Data.Ord (Ord, Ordering)
+import Data.Semigroup (Semigroup)
+import Fold.Pure.Type (Fold)
+import Data.Bool (Bool)
+import Data.Eq (Eq)
+import Numeric.Natural (Natural)
+
+import qualified Fold.Pure.Conversion as Convert
+import qualified Fold.Nonempty.Examples.Interesting as Nonempty
+import qualified Fold.ShortcutNonempty.Examples.Interesting as ShortcutNonempty
+import qualified Fold.Shortcut.Examples.Interesting as Shortcut
+
+{-| 'True' if the input contains no inputs -}
+null :: Fold a Bool
+null = Convert.shortcutFold Shortcut.null
+
+{-| Start with the first input, append each new input on the right
+with the given function -}
+magma :: (a -> a -> a) -> Fold a (Maybe a)
+magma step = Convert.nonemptyFold (Nonempty.magma step)
+
+{-| Append each new input on the right with ('<>') -}
+semigroup :: Semigroup a => Fold a (Maybe a)
+semigroup = Convert.nonemptyFold Nonempty.semigroup
+
+{-| The first input -}
+first :: Fold a (Maybe a)
+first = Convert.shortcutNonemptyFold ShortcutNonempty.first
+
+{-| The last input -}
+last :: Fold a (Maybe a)
+last = Convert.nonemptyFold Nonempty.last
+
+{-| The greatest input -}
+maximum :: Ord a => Fold a (Maybe a)
+maximum = Convert.nonemptyFold Nonempty.maximum
+
+{-| The greatest input with respect to the given comparison function -}
+maximumBy :: (a -> a -> Ordering) -> Fold a (Maybe a)
+maximumBy cmp = Convert.nonemptyFold (Nonempty.maximumBy cmp)
+
+{-| The least input -}
+minimum :: Ord a => Fold a (Maybe a)
+minimum = Convert.nonemptyFold Nonempty.minimum
+
+{-| The least input with respect to the given comparison function -}
+minimumBy :: (a -> a -> Ordering) -> Fold a (Maybe a)
+minimumBy cmp = Convert.nonemptyFold (Nonempty.minimumBy cmp)
+
+{-| 'True' if all inputs are 'True' -}
+and :: Fold Bool Bool
+and = Convert.shortcutFold Shortcut.and
+
+{-| 'True' if any input is 'True' -}
+or :: Fold Bool Bool
+or = Convert.shortcutFold Shortcut.or
+
+{-| 'True' if all inputs satisfy the predicate -}
+all :: (a -> Bool) -> Fold a Bool
+all predicate = Convert.shortcutFold (Shortcut.all predicate)
+
+{-| 'True' if any input satisfies the predicate -}
+any :: (a -> Bool) -> Fold a Bool
+any predicate = Convert.shortcutFold (Shortcut.any predicate)
+
+{-| 'True' if any input is equal to the given value -}
+element :: Eq a => a -> Fold a Bool
+element a = Convert.shortcutFold (Shortcut.element a)
+
+{-| 'False' if any input is equal to the given value -}
+notElement :: Eq a => a -> Fold a Bool
+notElement a = Convert.shortcutFold (Shortcut.notElement a)
+
+{-| The first input that satisfies the predicate, if any -}
+find :: (a -> Bool) -> Fold a (Maybe a)
+find ok = Convert.shortcutFold (Shortcut.find ok)
+
+{-| The /n/th input, where n=0 is the first input, if the index is in bounds -}
+index :: Natural -> Fold a (Maybe a)
+index i = Convert.shortcutFold (Shortcut.index i)
+
+{-| The index of the first input that matches the given value, if any -}
+elementIndex :: Eq a => a -> Fold a (Maybe Natural)
+elementIndex a = Convert.shortcutFold (Shortcut.elementIndex a)
+
+{-| The index of the first input that satisfies the predicate, if any -}
+findIndex :: (a -> Bool) -> Fold a (Maybe Natural)
+findIndex ok = Convert.shortcutFold (Shortcut.findIndex ok)
+
+{-| The @b@ from the first tuple where @a@ equals the given value, if any -}
+lookup :: Eq a => a -> Fold (a, b) (Maybe b)
+lookup a0 = Convert.shortcutFold (Shortcut.lookup a0)
diff --git a/source/Fold/Pure/Examples/Interesting.hs b/source/Fold/Pure/Examples/Interesting.hs
new file mode 100644
--- /dev/null
+++ b/source/Fold/Pure/Examples/Interesting.hs
@@ -0,0 +1,72 @@
+module Fold.Pure.Examples.Interesting
+  (
+    {- * Monoid -} monoid,
+    {- * Length -} length,
+    {- * Numeric -} sum, product, mean, variance, standardDeviation,
+    {- * List -} list, reverseList,
+  )
+  where
+
+import Fold.Pure.Type
+
+import Data.Function (id, ($), (.))
+import Data.Functor ((<$>))
+import Data.Monoid (Monoid, mempty)
+import Data.Semigroup ((<>))
+import Numeric.Natural (Natural)
+import Prelude (Floating, Fractional, Num, sqrt, (*), (+), (-), (/))
+
+import qualified Strict
+
+{-| Start with 'mempty', append each input on the right with ('<>') -}
+monoid :: Monoid a => Fold a a
+monoid = Fold{ initial = mempty, step = (<>), extract = id }
+
+{-| The number of inputs -}
+length :: Fold a Natural
+length = Fold{ initial = 0, step = \n _ -> n + 1, extract = id }
+
+{-| Adds the inputs -}
+sum :: Num a => Fold a a
+sum = Fold{ initial = 0, step = (+), extract = id }
+
+{-| Multiplies the inputs -}
+product :: Num a => Fold a a
+product = Fold{ initial = 1, step = (*), extract = id }
+
+{-| Numerically stable arithmetic mean of the inputs -}
+mean :: Fractional a => Fold a a
+mean = Fold
+    { initial = Strict.Tuple2 0 0
+    , step = \(Strict.Tuple2 x n) y ->
+        let n' = n + 1 in
+        Strict.Tuple2 (x + (y - x) / n') n'
+    , extract = \(Strict.Tuple2 x _) -> x
+    }
+
+{-| Numerically stable (population) variance over the inputs -}
+variance :: Fractional a => Fold a a
+variance = Fold
+    { initial = Strict.Tuple3 0 0 0
+    , step = \(Strict.Tuple3 n mean_ m2) x ->
+        let
+          n'     = n + 1
+          mean'  = (n * mean_ + x) / (n + 1)
+          delta  = x - mean_
+          m2'    = m2 + delta * delta * n / (n + 1)
+        in
+          Strict.Tuple3 n' mean' m2'
+    , extract = \(Strict.Tuple3 n _ m2) -> m2 / n
+    }
+
+{-| Numerically stable (population) standard deviation over the inputs -}
+standardDeviation :: Floating a => Fold a a
+standardDeviation = sqrt <$> variance
+
+{-| All the inputs -}
+list :: Fold a [a]
+list = Fold{ initial = id, step = \x a -> x . (a :), extract = ($ []) }
+
+{-| All the inputs in reverse order -}
+reverseList :: Fold a [a]
+reverseList = Fold{ initial = [], step = \x a -> a : x, extract = id }
diff --git a/source/Fold/Pure/Nonempty.hs b/source/Fold/Pure/Nonempty.hs
deleted file mode 100644
--- a/source/Fold/Pure/Nonempty.hs
+++ /dev/null
@@ -1,49 +0,0 @@
--- | Folds from "Fold.Nonempty.Examples" trivially lifted into 'Fold'
-module Fold.Pure.Nonempty
-  (
-    {- * General -} magma, semigroup,
-    {- * Endpoints -} first, last,
-    {- * Extrema -} maximum, minimum, maximumBy, minimumBy,
-  )
-  where
-
-import Data.Maybe (Maybe)
-import Data.Ord (Ord, Ordering)
-import Data.Semigroup (Semigroup)
-import Fold.Pure.Conversion (nonemptyFold)
-import Fold.Pure.Type (Fold)
-
-import qualified Fold.Nonempty.Examples as Nonempty
-
-{-| Start with the first input, append each new input on the right
-with the given function -}
-magma :: (a -> a -> a) -> Fold a (Maybe a)
-magma step = nonemptyFold (Nonempty.magma step)
-
-{-| Append each new input on the right with ('<>') -}
-semigroup :: Semigroup a => Fold a (Maybe a)
-semigroup = nonemptyFold Nonempty.semigroup
-
-{-| The first input -}
-first :: Fold a (Maybe a)
-first = nonemptyFold Nonempty.first
-
-{-| The last input -}
-last :: Fold a (Maybe a)
-last = nonemptyFold Nonempty.last
-
-{-| The greatest input -}
-maximum :: Ord a => Fold a (Maybe a)
-maximum = nonemptyFold Nonempty.maximum
-
-{-| The greatest input with respect to the given comparison function -}
-maximumBy :: (a -> a -> Ordering) -> Fold a (Maybe a)
-maximumBy cmp = nonemptyFold (Nonempty.maximumBy cmp)
-
-{-| The least input -}
-minimum :: Ord a => Fold a (Maybe a)
-minimum = nonemptyFold Nonempty.minimum
-
-{-| The least input with respect to the given comparison function -}
-minimumBy :: (a -> a -> Ordering) -> Fold a (Maybe a)
-minimumBy cmp = nonemptyFold (Nonempty.minimumBy cmp)
diff --git a/source/Fold/Shortcut.hs b/source/Fold/Shortcut.hs
new file mode 100644
--- /dev/null
+++ b/source/Fold/Shortcut.hs
@@ -0,0 +1,28 @@
+module Fold.Shortcut
+  (
+    {- * Type -} ShortcutFold (..),
+
+    {- * Run -} run,
+
+    {- * Examples -}
+    {- ** General -} magma, semigroup, monoid,
+    {- ** Endpoints -} first, last,
+    {- ** Extrema -} maximum, minimum, maximumBy, minimumBy,
+    {- ** Length -} null, length,
+    {- ** Boolean -} and, or, all, any,
+    {- ** Numeric -} sum, product, mean, variance, standardDeviation,
+    {- ** Search -} element, notElement, find, lookup,
+    {- ** Index -} index, findIndex, elementIndex,
+    {- ** List -} list, reverseList,
+
+    {- * Conversion -} fold, effectfulFold, nonemptyFold, shortcutNonemptyFold,
+
+    {- * Utilities -} demotivate,
+  )
+  where
+
+import Fold.Shortcut.Conversion
+import Fold.Shortcut.Examples
+import Fold.Shortcut.Run
+import Fold.Shortcut.Type
+import Fold.Shortcut.Utilities
diff --git a/source/Fold/Shortcut/Conversion.hs b/source/Fold/Shortcut/Conversion.hs
new file mode 100644
--- /dev/null
+++ b/source/Fold/Shortcut/Conversion.hs
@@ -0,0 +1,45 @@
+module Fold.Shortcut.Conversion where
+
+import Fold.Shortcut.Type
+
+import Data.Functor ((<$>))
+import Data.Functor.Identity (Identity)
+import Data.Maybe (Maybe (Just))
+import Fold.Effectful.Type (EffectfulFold)
+import Fold.Nonempty.Type (NonemptyFold)
+import Fold.Pure.Type (Fold (Fold))
+import Fold.ShortcutNonempty.Type (ShortcutNonemptyFold (ShortcutNonemptyFold))
+import Data.Void (absurd)
+
+import qualified Fold.Pure.Conversion as Fold
+import qualified Fold.Pure.Type as Fold
+import qualified Fold.ShortcutNonempty.Type as ShortcutNonempty
+import qualified Strict
+
+fold :: Fold a b -> ShortcutFold a b
+fold
+  Fold{ Fold.initial, Fold.step, Fold.extract } =
+    ShortcutFold
+      { initial = Alive Ambivalent initial
+      , step = \x a -> Alive Ambivalent (step x a)
+      , extractDead = absurd
+      , extractLive = extract
+      }
+
+effectfulFold :: EffectfulFold Identity a b -> ShortcutFold a b
+effectfulFold x = fold (Fold.effectfulFold x)
+
+nonemptyFold :: NonemptyFold a b -> ShortcutFold a (Maybe b)
+nonemptyFold x = fold (Fold.nonemptyFold x)
+
+shortcutNonemptyFold :: ShortcutNonemptyFold a b -> ShortcutFold a (Maybe b)
+shortcutNonemptyFold ShortcutNonemptyFold{ ShortcutNonempty.initial,
+        ShortcutNonempty.step, ShortcutNonempty.extractDead, ShortcutNonempty.extractLive } =
+    ShortcutFold
+      { initial = Alive Tenacious Strict.Nothing
+      , step = \xm a -> Strict.Just <$> case xm of
+            Strict.Nothing -> initial a
+            Strict.Just x -> step x a
+      , extractDead = \x -> Just (extractDead x)
+      , extractLive = \xm -> extractLive <$> Strict.lazy xm
+      }
diff --git a/source/Fold/Shortcut/Examples.hs b/source/Fold/Shortcut/Examples.hs
new file mode 100644
--- /dev/null
+++ b/source/Fold/Shortcut/Examples.hs
@@ -0,0 +1,16 @@
+module Fold.Shortcut.Examples
+  (
+    {- * General -} magma, semigroup, monoid,
+    {- * Endpoints -} first, last,
+    {- * Extrema -} maximum, minimum, maximumBy, minimumBy,
+    {- * Length -} null, length,
+    {- * Boolean -} and, or, all, any,
+    {- * Numeric -} sum, product, mean, variance, standardDeviation,
+    {- * Search -} element, notElement, find, lookup,
+    {- * Index -} index, findIndex, elementIndex,
+    {- * List -} list, reverseList,
+  )
+  where
+
+import Fold.Shortcut.Examples.Interesting
+import Fold.Shortcut.Examples.Boring
diff --git a/source/Fold/Shortcut/Examples/Boring.hs b/source/Fold/Shortcut/Examples/Boring.hs
new file mode 100644
--- /dev/null
+++ b/source/Fold/Shortcut/Examples/Boring.hs
@@ -0,0 +1,98 @@
+-- | Folds of other types trivially lifted into 'Shortcut'
+module Fold.Shortcut.Examples.Boring
+  (
+    {- * Arithmetic folds -} sum, product, mean, variance, standardDeviation,
+    {- * Counting inputs -} length,
+    {- * Min/max -} maximum, minimum, maximumBy, minimumBy,
+    {- * First/last -} first, last,
+    {- * General folds -} magma, semigroup, monoid,
+    {- * List folds -} list, reverseList,
+  )
+  where
+
+import Data.Maybe (Maybe)
+import Fold.Shortcut.Type (ShortcutFold)
+import Data.Semigroup (Semigroup)
+import Data.Ord (Ord, Ordering (GT), max, min)
+import Data.Monoid (Monoid)
+import Prelude (Floating, Fractional, Num)
+import Numeric.Natural (Natural)
+
+import qualified Fold.ShortcutNonempty.Examples.Interesting as ShortcutNonempty
+import qualified Fold.Nonempty.Examples.Interesting as Nonempty
+import qualified Fold.Pure.Examples.Interesting as Fold
+import qualified Fold.Shortcut.Conversion as Convert
+
+{-| The first input (tenacious) -}
+first :: ShortcutFold a (Maybe a)
+first = Convert.shortcutNonemptyFold ShortcutNonempty.first
+
+{-| Start with the first input, append each new input on the right
+    with the given function (ambivalent) -}
+magma :: (a -> a -> a) -> ShortcutFold a (Maybe a)
+magma step = Convert.nonemptyFold (Nonempty.magma step)
+
+{-| Append each new input on the right with '<>' (ambivalent) -}
+semigroup :: Semigroup a => ShortcutFold a (Maybe a)
+semigroup = Convert.nonemptyFold Nonempty.semigroup
+
+{-| The last input (ambivalent) -}
+last :: ShortcutFold a (Maybe a)
+last = Convert.nonemptyFold Nonempty.last
+
+{-| The greatest input (ambivalent) -}
+maximum :: Ord a => ShortcutFold a (Maybe a)
+maximum = magma max
+
+{-| The greatest input with respect to the given comparison function
+    (ambivalent) -}
+maximumBy :: (a -> a -> Ordering) -> ShortcutFold a (Maybe a)
+maximumBy cmp = magma (\x y -> case cmp x y of { GT -> x; _ -> y })
+
+{-| The least input (ambivalent) -}
+minimum :: Ord a => ShortcutFold a (Maybe a)
+minimum = magma min
+
+{-| The least input with respect to the given comparison function
+    (ambivalent) -}
+minimumBy :: (a -> a -> Ordering) -> ShortcutFold a (Maybe a)
+minimumBy cmp = magma (\x y -> case cmp x y of { GT -> y; _ -> x })
+
+{-| All the inputs (ambivalent) -}
+list :: ShortcutFold a [a]
+list = Convert.fold Fold.list
+
+{-| All the inputs in reverse order (ambivalent) -}
+reverseList :: ShortcutFold a [a]
+reverseList = Convert.fold Fold.reverseList
+
+{-| Start with 'mempty', append each input on the right with '<>'
+    (ambivalent)-}
+monoid :: Monoid a => ShortcutFold a a
+monoid = Convert.fold Fold.monoid
+
+{-| The number of inputs (ambivalent) -}
+length :: ShortcutFold a Natural
+length = Convert.fold Fold.length
+
+{-| Adds the inputs (ambivalent) -}
+sum :: Num a => ShortcutFold a a
+sum = Convert.fold Fold.sum
+
+{-| Multiplies the inputs (ambivalent) -}
+product :: Num a => ShortcutFold a a
+product = Convert.fold Fold.product
+
+{-| Numerically stable arithmetic mean of the inputs (ambivalent) -}
+mean :: Fractional a => ShortcutFold a a
+mean = Convert.fold Fold.mean
+
+{-| Numerically stable (population) variance over the
+    inputs (ambivalent) -}
+variance :: Fractional a => ShortcutFold a a
+variance = Convert.fold Fold.variance
+
+{-| Numerically stable (population) standard deviation over the
+    inputs (ambivalent) -}
+standardDeviation :: Floating a => ShortcutFold a a
+standardDeviation = Convert.fold Fold.standardDeviation
diff --git a/source/Fold/Shortcut/Examples/Interesting.hs b/source/Fold/Shortcut/Examples/Interesting.hs
new file mode 100644
--- /dev/null
+++ b/source/Fold/Shortcut/Examples/Interesting.hs
@@ -0,0 +1,118 @@
+module Fold.Shortcut.Examples.Interesting
+  (
+    {- * Length -} null,
+    {- * Boolean -} and, or, all, any,
+    {- * Search -} element, notElement, find, lookup,
+    {- * Index -} index, findIndex, elementIndex,
+  )
+  where
+
+import Fold.Shortcut.Type
+
+import Control.Applicative (liftA2)
+import Data.Bool (Bool (False, True))
+import Data.Eq (Eq, (/=), (==))
+import Data.Functor (($>), (<&>))
+import Data.Maybe (Maybe (Just, Nothing))
+import Numeric.Natural (Natural)
+import Prelude ((-))
+import Fold.Shortcut.Conversion (fold)
+import Fold.Shortcut.Utilities (demotivate)
+
+import qualified Fold.Pure.Examples.Interesting as Fold
+
+{-| 'True' if the input contains no inputs (tenacious) -}
+null :: ShortcutFold a Bool
+null = ShortcutFold
+  { initial = Alive Tenacious ()
+  , step = \() _ -> Dead ()
+  , extractLive = \() -> True
+  , extractDead = \() -> False
+  }
+
+{-| 'True' if all inputs are 'True' (tenacious) -}
+and :: ShortcutFold Bool Bool
+and = ShortcutFold
+  { initial = Alive Tenacious ()
+  , step = \_ a -> if a then Alive Tenacious () else Dead ()
+  , extractLive = \() -> True
+  , extractDead = \() -> False
+  }
+
+{-| 'True' if any input is 'True' (tenacious) -}
+or :: ShortcutFold Bool Bool
+or = ShortcutFold
+  { initial = Alive Tenacious ()
+  , step = \() a -> if a then Dead () else Alive Tenacious ()
+  , extractLive = \() -> False
+  , extractDead = \() -> True
+  }
+
+{-| 'True' if all inputs satisfy the predicate (tenacious) -}
+all :: (a -> Bool) -> ShortcutFold a Bool
+all predicate = ShortcutFold
+  { initial = Alive Tenacious ()
+  , step = \() a -> if predicate a then Alive Tenacious () else Dead ()
+  , extractLive = \() -> True
+  , extractDead = \() -> False
+  }
+
+{-| 'True' if any input satisfies the predicate (tenacious) -}
+any :: (a -> Bool) -> ShortcutFold a Bool
+any predicate = ShortcutFold
+  { initial = Alive Tenacious ()
+  , step = \_ a -> if predicate a then Dead () else Alive Tenacious ()
+  , extractLive = \() -> False
+  , extractDead = \() -> True
+  }
+
+{-| 'True' if any input is equal to the given value (tenacious) -}
+element :: Eq a => a -> ShortcutFold a Bool
+element a = any (a ==)
+
+{-| 'False' if any input is equal to the given value (tenacious) -}
+notElement :: Eq a => a -> ShortcutFold a Bool
+notElement a = all (a /=)
+
+{-| The first input that satisfies the predicate, if any (tenacious) -}
+find :: (a -> Bool) -> ShortcutFold a (Maybe a)
+find ok = ShortcutFold
+    { initial = Alive Tenacious ()
+    , step = \() a -> if ok a then Dead a else Alive Tenacious ()
+    , extractDead = Just
+    , extractLive = \() -> Nothing
+    }
+
+{-| The /n/th input, where n=0 is the first input, if the index is in
+    bounds (tenacious) -}
+index :: Natural -> ShortcutFold a (Maybe a)
+index i = ShortcutFold
+    { initial = Alive Tenacious i
+    , step = \i' a -> if i' == 0 then Dead a else Alive Tenacious (i' - 1)
+    , extractDead = Just
+    , extractLive = \_ -> Nothing
+    }
+
+{-| The index of the first input that matches the given value, if any
+    (tenacious) -}
+elementIndex :: Eq a => a -> ShortcutFold a (Maybe Natural)
+elementIndex a = findIndex (a ==)
+
+{-| The index of the first input that satisfies the predicate, if any
+    (tenacious) -}
+findIndex :: (a -> Bool) -> ShortcutFold a (Maybe Natural)
+findIndex ok = demotivate
+  (
+    liftA2 (,) (fold Fold.length) (find ok)
+    <&> \(n, found) -> found $> (n - 1)
+  )
+
+{-| The @b@ from the first tuple where @a@ equals the given value,
+    if any (tenacious) -}
+lookup :: Eq a => a -> ShortcutFold (a, b) (Maybe b)
+lookup a0 = ShortcutFold
+    { initial = Alive Tenacious ()
+    , step = \() (a, b) -> if a == a0 then Dead b else Alive Tenacious ()
+    , extractLive = \() -> Nothing
+    , extractDead = Just
+    }
diff --git a/source/Fold/Shortcut/Run.hs b/source/Fold/Shortcut/Run.hs
new file mode 100644
--- /dev/null
+++ b/source/Fold/Shortcut/Run.hs
@@ -0,0 +1,13 @@
+module Fold.Shortcut.Run where
+
+import Fold.Shortcut.Type
+
+{-| Fold a listlike container to a single summary result, forcing
+    only enough input to satisfy the short-cutting fold -}
+run :: ShortcutFold a b -> [a] -> b
+run ShortcutFold{ initial, step, extractDead, extractLive } = go initial
+  where
+    go (Alive Tenacious x) (a : as)  =  go (step x a) as
+    go (Alive Tenacious x) []        =  extractLive x
+    go (Alive Ambivalent x) _        =  extractLive x
+    go (Dead x)             _        =  extractDead x
diff --git a/source/Fold/Shortcut/Type.hs b/source/Fold/Shortcut/Type.hs
new file mode 100644
--- /dev/null
+++ b/source/Fold/Shortcut/Type.hs
@@ -0,0 +1,64 @@
+module Fold.Shortcut.Type
+  (
+    ShortcutFold (..),
+    Will (..), Vitality (..),
+  )
+  where
+
+import Control.Applicative (Applicative, liftA2, pure, (<*>))
+import Data.Functor (Functor, fmap)
+import Data.Monoid (Monoid, mempty)
+import Data.Semigroup (Semigroup, (<>))
+import Strict (Will (..), 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@ -}
+data ShortcutFold a b = forall x y. ShortcutFold
+    { initial :: Vitality x y
+    , step :: y -> a -> Vitality x y
+    , extractDead :: x -> b
+    , extractLive :: y -> b
+    }
+
+instance Functor (ShortcutFold a) where
+    fmap f ShortcutFold{ step, initial, extractDead, extractLive } =
+        ShortcutFold
+          { initial
+          , step
+          , extractDead = \x -> f (extractDead x)
+          , extractLive = \x -> f (extractLive x)
+          }
+
+instance Applicative (ShortcutFold a) where
+    pure b = ShortcutFold
+        { initial = Dead ()
+        , step = absurd
+        , extractDead = \() -> b
+        , extractLive = absurd
+        }
+
+    (<*>)
+        ShortcutFold{ initial = initialL, step = stepL, extractDead = extractDeadL, extractLive = extractLiveL }
+        ShortcutFold{ initial = initialR, step = stepR, extractDead = extractDeadR, extractLive = extractLiveR } =
+          ShortcutFold
+            { initial = Strict.vitality2 initialL initialR
+            , step = \(Strict.Tuple2 xL xR) a -> Strict.vitality2
+                (Strict.unlessDead (\x -> stepL x a) xL)
+                (Strict.unlessDead (\x -> stepR x a) xR)
+            , extractDead = extract
+            , extractLive = extract
+            }
+          where
+            extract(Strict.Tuple2 xL xR) = f x
+              where
+                f = case xL of { Dead a -> extractDeadL a; Alive _ b -> extractLiveL b }
+                x = case xR of { Dead a -> extractDeadR a; Alive _ b -> extractLiveR b }
+
+instance Semigroup b => Semigroup (ShortcutFold a b) where
+    (<>) = liftA2 (<>)
+
+instance Monoid b => Monoid (ShortcutFold a b) where
+    mempty = pure mempty
diff --git a/source/Fold/Shortcut/Utilities.hs b/source/Fold/Shortcut/Utilities.hs
new file mode 100644
--- /dev/null
+++ b/source/Fold/Shortcut/Utilities.hs
@@ -0,0 +1,19 @@
+module Fold.Shortcut.Utilities where
+
+import Fold.Shortcut.Type
+
+import Strict (willSave)
+
+import qualified Strict
+
+{-| Causes a shortcut fold to stop once it becomes ambivalent -}
+demotivate :: ShortcutFold a b -> ShortcutFold a b
+demotivate ShortcutFold{ initial, step, extractDead, extractLive } =
+  ShortcutFold
+    { initial = willSave initial
+    , step = \x a -> willSave (step x a)
+    , extractDead = \e -> case e of
+          Strict.Left x -> extractDead x
+          Strict.Right x -> extractLive x
+    , extractLive = extractLive
+    }
diff --git a/source/Fold/ShortcutNonempty.hs b/source/Fold/ShortcutNonempty.hs
new file mode 100644
--- /dev/null
+++ b/source/Fold/ShortcutNonempty.hs
@@ -0,0 +1,28 @@
+module Fold.ShortcutNonempty
+  (
+    {- * Type -} ShortcutNonemptyFold (..),
+
+    {- * Run -} run,
+
+    {- * Examples -}
+    {- ** General -} magma, semigroup, monoid,
+    {- ** Endpoints -} first, last,
+    {- ** Extrema -} maximum, minimum, maximumBy, minimumBy,
+    {- ** Length -} length,
+    {- ** Boolean -} and, or, all, any,
+    {- ** Numeric -} sum, product, mean, variance, standardDeviation,
+    {- ** Search -} element, notElement, find, lookup,
+    {- ** Index -} index, findIndex, elementIndex,
+    {- ** List -} list, reverseList,
+
+    {- * Conversion -} fold, effectfulFold, nonemptyFold, shortcutFold,
+
+    {- * Utilities -} demotivate,
+  )
+  where
+
+import Fold.ShortcutNonempty.Conversion
+import Fold.ShortcutNonempty.Examples
+import Fold.ShortcutNonempty.Run
+import Fold.ShortcutNonempty.Type
+import Fold.ShortcutNonempty.Utilities
diff --git a/source/Fold/ShortcutNonempty/Conversion.hs b/source/Fold/ShortcutNonempty/Conversion.hs
new file mode 100644
--- /dev/null
+++ b/source/Fold/ShortcutNonempty/Conversion.hs
@@ -0,0 +1,51 @@
+module Fold.ShortcutNonempty.Conversion where
+
+import Fold.ShortcutNonempty.Type
+
+import Data.Functor.Identity (Identity)
+import Fold.Effectful.Type (EffectfulFold)
+import Fold.Nonempty.Type (NonemptyFold)
+import Fold.Pure.Type (Fold (Fold))
+import Fold.Shortcut.Type (ShortcutFold (ShortcutFold))
+import Fold.Nonempty.Type (NonemptyFold (NonemptyFold))
+import Data.Void (absurd)
+
+import qualified Fold.Pure.Conversion as Fold
+import qualified Fold.Pure.Type as Fold
+import qualified Fold.Shortcut.Type as Shortcut
+import qualified Fold.Nonempty.Type as Nonempty
+
+fold :: Fold a b -> ShortcutNonemptyFold a b
+fold
+  Fold{ Fold.initial, Fold.step, Fold.extract } =
+    ShortcutNonemptyFold
+      { initial = \a -> Alive Ambivalent (step initial a)
+      , step = \x a -> Alive Ambivalent (step x a)
+      , extractDead = absurd
+      , extractLive = extract
+      }
+
+effectfulFold :: EffectfulFold Identity a b -> ShortcutNonemptyFold a b
+effectfulFold x = fold (Fold.effectfulFold x)
+
+nonemptyFold :: NonemptyFold a b -> ShortcutNonemptyFold a b
+nonemptyFold
+  NonemptyFold{ Nonempty.initial, Nonempty.step, Nonempty.extract } =
+    ShortcutNonemptyFold
+      { initial = \a -> Alive Ambivalent (initial a)
+      , step = \x a -> Alive Ambivalent (step x a)
+      , extractDead = absurd
+      , extractLive = extract
+      }
+
+shortcutFold :: ShortcutFold a b -> ShortcutNonemptyFold a b
+shortcutFold ShortcutFold{ Shortcut.initial, Shortcut.step,
+        Shortcut.extractDead, Shortcut.extractLive } =
+    ShortcutNonemptyFold
+      { initial = case initial of
+            Dead    x -> \_ -> Dead x
+            Alive _ x -> step x
+      , step = step
+      , extractDead = extractDead
+      , extractLive = extractLive
+      }
diff --git a/source/Fold/ShortcutNonempty/Examples.hs b/source/Fold/ShortcutNonempty/Examples.hs
new file mode 100644
--- /dev/null
+++ b/source/Fold/ShortcutNonempty/Examples.hs
@@ -0,0 +1,16 @@
+module Fold.ShortcutNonempty.Examples
+  (
+    {- * General -} magma, semigroup, monoid,
+    {- * Endpoints -} first, last,
+    {- * Extrema -} maximum, minimum, maximumBy, minimumBy,
+    {- * Length -} length,
+    {- * Boolean -} and, or, all, any,
+    {- * Numeric -} sum, product, mean, variance, standardDeviation,
+    {- * Search -} element, notElement, find, lookup,
+    {- * Index -} index, findIndex, elementIndex,
+    {- * List -} list, reverseList,
+  )
+  where
+
+import Fold.ShortcutNonempty.Examples.Interesting
+import Fold.ShortcutNonempty.Examples.Boring
diff --git a/source/Fold/ShortcutNonempty/Examples/Boring.hs b/source/Fold/ShortcutNonempty/Examples/Boring.hs
new file mode 100644
--- /dev/null
+++ b/source/Fold/ShortcutNonempty/Examples/Boring.hs
@@ -0,0 +1,147 @@
+-- | Folds of other types trivially lifted into 'ShortcutNonempty'
+module Fold.ShortcutNonempty.Examples.Boring
+  (
+    {- * Search -} element, notElement, find, lookup,
+    {- * Arithmetic folds -} sum, product, mean, variance, standardDeviation,
+    {- * Working with indices -} index, findIndex, elementIndex,
+    {- * Counting inputs -} length,
+    {- * Boolean folds -} and, or, all, any,
+    {- * Min/max -} maximum, minimum, maximumBy, minimumBy,
+    {- * First/last -} last,
+    {- * General folds -} magma, semigroup, monoid,
+    {- * List folds -} list, reverseList,
+  )
+  where
+
+import Data.Maybe (Maybe)
+import Fold.ShortcutNonempty.Type (ShortcutNonemptyFold)
+import Data.Semigroup (Semigroup)
+import Data.Ord (Ord, Ordering)
+import Data.Monoid (Monoid)
+import Prelude (Floating, Fractional, Num)
+import Data.Bool (Bool)
+import Data.Eq (Eq)
+import Numeric.Natural (Natural)
+
+import qualified Fold.Shortcut.Examples.Interesting as Shortcut
+import qualified Fold.Nonempty.Examples.Interesting as Nonempty
+import qualified Fold.Pure.Examples.Interesting as Pure
+import qualified Fold.ShortcutNonempty.Conversion as Convert
+
+{-| Start with 'mempty', append each input on the right
+    with '<>' (ambivalent) -}
+monoid :: Monoid a => ShortcutNonemptyFold a a
+monoid = Convert.fold Pure.monoid
+
+{-| The number of inputs (ambivalent) -}
+length :: ShortcutNonemptyFold a Natural
+length = Convert.fold Pure.length
+
+{-| 'True' if all inputs are 'True' (tenacious) -}
+and :: ShortcutNonemptyFold Bool Bool
+and = Convert.shortcutFold Shortcut.and
+
+{-| 'True' if any input is 'True' (tenacious) -}
+or :: ShortcutNonemptyFold Bool Bool
+or = Convert.shortcutFold Shortcut.or
+
+{-| 'True' if all inputs satisfy the predicate (tenacious) -}
+all :: (a -> Bool) -> ShortcutNonemptyFold a Bool
+all predicate = Convert.shortcutFold (Shortcut.all predicate)
+
+{-| 'True' if any input satisfies the predicate (tenacious) -}
+any :: (a -> Bool) -> ShortcutNonemptyFold a Bool
+any predicate = Convert.shortcutFold (Shortcut.any predicate)
+
+{-| Adds the inputs (ambivalent) -}
+sum :: Num a => ShortcutNonemptyFold a a
+sum = Convert.fold Pure.sum
+
+{-| Multiplies the inputs (ambivalent) -}
+product :: Num a => ShortcutNonemptyFold a a
+product = Convert.fold Pure.product
+
+{-| Numerically stable arithmetic mean of the inputs (ambivalent) -}
+mean :: Fractional a => ShortcutNonemptyFold a a
+mean = Convert.fold Pure.mean
+
+{-| Numerically stable (population) variance over the
+    inputs (ambivalent) -}
+variance :: Fractional a => ShortcutNonemptyFold a a
+variance = Convert.fold Pure.variance
+
+{-| Numerically stable (population) standard deviation over
+    the inputs (ambivalent) -}
+standardDeviation :: Floating a => ShortcutNonemptyFold a a
+standardDeviation = Convert.fold Pure.standardDeviation
+
+{-| 'True' if any input is equal to the given value (tenacious) -}
+element :: Eq a => a -> ShortcutNonemptyFold a Bool
+element a = Convert.shortcutFold (Shortcut.element a)
+
+{-| 'False' if any input is equal to the given value (tenacious) -}
+notElement :: Eq a => a -> ShortcutNonemptyFold a Bool
+notElement a = Convert.shortcutFold (Shortcut.notElement a)
+
+{-| The first input that satisfies the predicate, if any (tenacious) -}
+find :: (a -> Bool) -> ShortcutNonemptyFold a (Maybe a)
+find ok = Convert.shortcutFold (Shortcut.find ok)
+
+{-| The /n/th input, where n=0 is the first input, if the index
+    is in bounds (tenacious) -}
+index :: Natural -> ShortcutNonemptyFold a (Maybe a)
+index i = Convert.shortcutFold (Shortcut.index i)
+
+{-| The index of the first input that matches the given value,
+    if any (tenacious) -}
+elementIndex :: Eq a => a -> ShortcutNonemptyFold a (Maybe Natural)
+elementIndex a = Convert.shortcutFold (Shortcut.elementIndex a)
+
+{-| The index of the first input that satisfies the predicate,
+    if any (tenacious) -}
+findIndex :: (a -> Bool) -> ShortcutNonemptyFold a (Maybe Natural)
+findIndex ok = Convert.shortcutFold (Shortcut.findIndex ok)
+
+{-| The @b@ from the first tuple where @a@ equals the given value,
+    if any (tenacious) -}
+lookup :: Eq a => a -> ShortcutNonemptyFold (a, b) (Maybe b)
+lookup a = Convert.shortcutFold (Shortcut.lookup a)
+
+{-| All the inputs (ambivalent) -}
+list :: ShortcutNonemptyFold a [a]
+list = Convert.fold Pure.list
+
+{-| All the inputs in reverse order (ambivalent) -}
+reverseList :: ShortcutNonemptyFold a [a]
+reverseList = Convert.fold Pure.reverseList
+
+{-| Start with the first input, append each new input on the right
+    with the given function (ambivalent) -}
+magma :: (a -> a -> a) -> ShortcutNonemptyFold a a
+magma step = Convert.nonemptyFold (Nonempty.magma step)
+
+{-| Append each new input on the right with '<>' (ambivalent) -}
+semigroup :: Semigroup a => ShortcutNonemptyFold a a
+semigroup = Convert.nonemptyFold Nonempty.semigroup
+
+{-| The last input  (ambivalent) -}
+last :: ShortcutNonemptyFold a a
+last = Convert.nonemptyFold Nonempty.last
+
+{-| The greatest input (ambivalent) -}
+maximum :: Ord a => ShortcutNonemptyFold a a
+maximum = Convert.nonemptyFold Nonempty.maximum
+
+{-| The greatest input with respect to the given comparison
+    function (ambivalent) -}
+maximumBy :: (a -> a -> Ordering) -> ShortcutNonemptyFold a a
+maximumBy cmp = Convert.nonemptyFold (Nonempty.maximumBy cmp)
+
+{-| The least input (ambivalent) -}
+minimum :: Ord a => ShortcutNonemptyFold a a
+minimum = Convert.nonemptyFold Nonempty.minimum
+
+{-| The least input with respect to the given comparison
+    function (ambivalent) -}
+minimumBy :: (a -> a -> Ordering) -> ShortcutNonemptyFold a a
+minimumBy cmp = Convert.nonemptyFold (Nonempty.minimumBy cmp)
diff --git a/source/Fold/ShortcutNonempty/Examples/Interesting.hs b/source/Fold/ShortcutNonempty/Examples/Interesting.hs
new file mode 100644
--- /dev/null
+++ b/source/Fold/ShortcutNonempty/Examples/Interesting.hs
@@ -0,0 +1,15 @@
+module Fold.ShortcutNonempty.Examples.Interesting where
+
+import Fold.ShortcutNonempty.Type
+
+import Data.Function (id)
+import Data.Void (absurd)
+
+{-| The first input (tenacious) -}
+first :: ShortcutNonemptyFold a a
+first = ShortcutNonemptyFold
+  { initial = Dead
+  , step = absurd
+  , extractDead = id
+  , extractLive = absurd
+  }
diff --git a/source/Fold/ShortcutNonempty/Run.hs b/source/Fold/ShortcutNonempty/Run.hs
new file mode 100644
--- /dev/null
+++ b/source/Fold/ShortcutNonempty/Run.hs
@@ -0,0 +1,16 @@
+module Fold.ShortcutNonempty.Run where
+
+import Fold.ShortcutNonempty.Type
+
+import Data.List.NonEmpty (NonEmpty ((:|)))
+
+{-| Fold a nonempty listlike container to a single summary result,
+    forcing only enough input to satisfy the short-cutting fold -}
+run :: ShortcutNonemptyFold a b -> NonEmpty a -> b
+run ShortcutNonemptyFold{ initial, step, extractDead, extractLive } =
+    \(z :| as) -> go (initial z) as
+  where
+    go (Alive Tenacious x)  (a : as)  =  go (step x a) as
+    go (Alive Tenacious x)  []        =  extractLive x
+    go (Alive Ambivalent x) _         =  extractLive x
+    go (Dead x)             _         =  extractDead x
diff --git a/source/Fold/ShortcutNonempty/Type.hs b/source/Fold/ShortcutNonempty/Type.hs
new file mode 100644
--- /dev/null
+++ b/source/Fold/ShortcutNonempty/Type.hs
@@ -0,0 +1,64 @@
+module Fold.ShortcutNonempty.Type
+  (
+    ShortcutNonemptyFold (..),
+    Will (..), Vitality (..),
+  )
+  where
+
+import Control.Applicative (Applicative, liftA2, pure, (<*>))
+import Data.Functor (Functor, fmap)
+import Data.Monoid (Monoid, mempty)
+import Data.Semigroup (Semigroup, (<>))
+import Strict (Will (..), 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@ -}
+data ShortcutNonemptyFold a b = forall x y. ShortcutNonemptyFold
+    { initial :: a -> Vitality x y
+    , step :: y -> a -> Vitality x y
+    , extractDead :: x -> b
+    , extractLive :: y -> b
+    }
+
+instance Functor (ShortcutNonemptyFold a) where
+    fmap f ShortcutNonemptyFold{ step, initial, extractDead, extractLive } =
+        ShortcutNonemptyFold
+          { initial
+          , step
+          , extractDead = \x -> f (extractDead x)
+          , extractLive = \x -> f (extractLive x)
+          }
+
+instance Applicative (ShortcutNonemptyFold a) where
+    pure b = ShortcutNonemptyFold
+        { initial = \_ -> Dead ()
+        , step = absurd
+        , extractDead = \() -> b
+        , extractLive = absurd
+        }
+
+    (<*>)
+        ShortcutNonemptyFold{ initial = initialL, step = stepL, extractDead = extractDeadL, extractLive = extractLiveL }
+        ShortcutNonemptyFold{ initial = initialR, step = stepR, extractDead = extractDeadR, extractLive = extractLiveR } =
+          ShortcutNonemptyFold
+            { initial = \a -> Strict.vitality2 (initialL a) (initialR a)
+            , step = \(Strict.Tuple2 xL xR) a -> Strict.vitality2
+                (Strict.unlessDead (\x -> stepL x a) xL)
+                (Strict.unlessDead (\x -> stepR x a) xR)
+            , extractDead = extract
+            , extractLive = extract
+            }
+          where
+            extract(Strict.Tuple2 xL xR) = f x
+              where
+                f = case xL of { Dead a -> extractDeadL a; Alive _ b -> extractLiveL b }
+                x = case xR of { Dead a -> extractDeadR a; Alive _ b -> extractLiveR b }
+
+instance Semigroup b => Semigroup (ShortcutNonemptyFold a b) where
+    (<>) = liftA2 (<>)
+
+instance Monoid b => Monoid (ShortcutNonemptyFold a b) where
+    mempty = pure mempty
diff --git a/source/Fold/ShortcutNonempty/Utilities.hs b/source/Fold/ShortcutNonempty/Utilities.hs
new file mode 100644
--- /dev/null
+++ b/source/Fold/ShortcutNonempty/Utilities.hs
@@ -0,0 +1,19 @@
+module Fold.ShortcutNonempty.Utilities where
+
+import Fold.ShortcutNonempty.Type
+
+import Strict (willSave)
+
+import qualified Strict
+
+{-| Causes a shortcut fold to stop once it becomes ambivalent -}
+demotivate :: ShortcutNonemptyFold a b -> ShortcutNonemptyFold a b
+demotivate ShortcutNonemptyFold{ initial, step, extractDead, extractLive } =
+  ShortcutNonemptyFold
+    { initial = \a -> willSave (initial a)
+    , step = \x a -> willSave (step x a)
+    , extractDead = \e -> case e of
+          Strict.Left x -> extractDead x
+          Strict.Right x -> extractLive x
+    , extractLive = extractLive
+    }
diff --git a/source/Fold/Types.hs b/source/Fold/Types.hs
--- a/source/Fold/Types.hs
+++ b/source/Fold/Types.hs
@@ -1,3 +1,3 @@
-module Fold.Types (Fold, NonemptyFold, EffectfulFold) where
+module Fold.Types (Fold, NonemptyFold, EffectfulFold, ShortcutFold, ShortcutNonemptyFold) where
 
 import Fold
diff --git a/source/Strict.hs b/source/Strict.hs
--- a/source/Strict.hs
+++ b/source/Strict.hs
@@ -7,11 +7,14 @@
     {- * Maybe -} Maybe (..), lazy, strict,
     {- * Either -} Either (..), hush,
     {- * Tuples -} Tuple2 (..), Tuple3 (..),
+    {- * Shortcut -} Vitality (..), Will (..),
+        unlessDead, vitality2, willSave,
   )
   where
 
-import Data.Semigroup (Semigroup, (<>))
+import Data.Functor (Functor (..))
 import Data.Monoid (Monoid, mempty)
+import Data.Semigroup (Semigroup, (<>))
 
 import qualified Data.Maybe as Lazy
 
@@ -42,3 +45,34 @@
 data Tuple2 a b = Tuple2 a b
 
 data Tuple3 a b c = Tuple3 a b c
+
+data Will = Ambivalent | Tenacious
+
+instance Semigroup Will where
+    Tenacious <> _ = Tenacious
+    _ <> Tenacious = Tenacious
+    _ <> _ = Ambivalent
+
+instance Monoid Will where
+    mempty = Ambivalent
+
+data Vitality a b = Dead a | Alive Will b
+    deriving Functor
+
+unlessDead :: (b -> Vitality a b) -> Vitality a b -> Vitality a b
+unlessDead f s = case s of { Alive _ x -> f x; _ -> s }
+
+willSave :: Vitality a b -> Vitality (Either a b) b
+willSave v = case v of
+    Dead x -> Dead (Left x)
+    Alive Ambivalent x -> Dead (Right x)
+    Alive Tenacious x -> Alive Tenacious x
+
+type Vitality' a = Vitality a a
+
+vitality2 :: Vitality a1 b1 -> Vitality a2 b2
+    -> Vitality' (Strict.Tuple2 (Vitality a1 b1) (Vitality a2 b2))
+vitality2 a@(Alive v1 _) b@(Alive v2 _) = Alive (v1 <> v2) (Strict.Tuple2 a b)
+vitality2 a@(Dead _)     b@(Alive v _)  = Alive v          (Strict.Tuple2 a b)
+vitality2 a@(Alive v _)  b@(Dead _)     = Alive v          (Strict.Tuple2 a b)
+vitality2 a@(Dead _)     b@(Dead _)     = Dead             (Strict.Tuple2 a b)
diff --git a/test/Main.hs b/test/Main.hs
--- a/test/Main.hs
+++ b/test/Main.hs
@@ -7,9 +7,13 @@
 import qualified Spec.Pure
 import qualified Spec.Nonempty
 import qualified Spec.Effectful
+import qualified Spec.Shortcut
+import qualified Spec.ShortcutNonempty
 
 main :: IO ()
 main = hspec do
     Spec.Pure.spec
     Spec.Nonempty.spec
     Spec.Effectful.spec
+    Spec.Shortcut.spec
+    Spec.ShortcutNonempty.spec
diff --git a/test/Spec/Effectful.hs b/test/Spec/Effectful.hs
--- a/test/Spec/Effectful.hs
+++ b/test/Spec/Effectful.hs
@@ -13,6 +13,7 @@
 import Data.Monoid (mempty)
 import Data.Semigroup (Sum (Sum), (<>))
 import Prelude ((>), String, Integer, (+), (*))
+import Data.Bool (Bool (..))
 
 import qualified Data.List as List
 
@@ -83,3 +84,11 @@
             shouldBe @(Identity Integer)
                 (run (prefilter (Identity . p) f) xs)
                 (run f (List.filter p xs))
+
+    describe "null" do
+        it "True for []" do
+            run null ([] :: [Integer]) `shouldBe` Identity True
+        it "False for anything else" do
+            run null ([1] :: [Integer]) `shouldBe` Identity False
+            run null ([1,2] :: [Integer]) `shouldBe` Identity False
+            run null ([1,2,3] :: [Integer]) `shouldBe` Identity False
diff --git a/test/Spec/Pure.hs b/test/Spec/Pure.hs
--- a/test/Spec/Pure.hs
+++ b/test/Spec/Pure.hs
@@ -12,6 +12,7 @@
 import Data.Monoid (mempty)
 import Data.Semigroup (Sum (Sum))
 import Prelude ((>), String, Integer, (+), (*))
+import Data.Bool (Bool (..))
 
 import qualified Data.Foldable as Foldable
 import qualified Data.List as List
@@ -116,3 +117,23 @@
         describe "reverseList" do
             it "gets all inputs in reverse" do
                 run reverseList xs `shouldBe` [4, 3, 2, 1]
+
+    describe "endpoint functions" do
+        describe "first" do
+            it "gets the first item" do
+                run first ([5, 4, 3] :: [Integer]) `shouldBe` Just 5
+            it "returns Nothing with no input" do
+                run first ([] :: [Integer]) `shouldBe` Nothing
+        describe "last" do
+            it "gets the last item" do
+                run last ([5, 4, 3] :: [Integer]) `shouldBe` Just 3
+            it "returns Nothing with no input" do
+                run last ([] :: [Integer]) `shouldBe` Nothing
+
+    describe "null" do
+        it "True for []" do
+            run null ([] :: [Integer]) `shouldBe` True
+        it "False for anything else" do
+            run null ([1] :: [Integer]) `shouldBe` False
+            run null ([1,2] :: [Integer]) `shouldBe` False
+            run null ([1,2,3] :: [Integer]) `shouldBe` False
diff --git a/test/Spec/Shortcut.hs b/test/Spec/Shortcut.hs
new file mode 100644
--- /dev/null
+++ b/test/Spec/Shortcut.hs
@@ -0,0 +1,81 @@
+module Spec.Shortcut where
+
+import Fold.Shortcut
+
+import Test.Hspec
+
+import Control.Applicative (pure, (<$>), (<*>))
+import Prelude (Integer, undefined)
+import Data.Maybe (Maybe (Just, Nothing))
+import Data.List ((++))
+import Data.Bool (Bool (..))
+
+import qualified Data.Char as Char
+
+spec :: SpecWith ()
+spec = describe "ShortcutFold" do
+
+    it "Applicative" do
+        let x = do
+                  a <- length
+                  b <- find Char.isLetter
+                  c <- elementIndex 'x'
+                  d <- elementIndex 'y'
+                  e <- last
+                  pure (a, b, c, d, e)
+        run x ("1234xyz" ++ undefined) `shouldBe` (6, Just 'x', Just 4, Just 5, Just 'y')
+
+    describe "first" do
+        it "gets the first item" do
+            shouldBe @(Maybe Integer) (run first [5, 4, 3]) (Just 5)
+        it "is lazy" do
+            shouldBe @(Maybe Integer) (run first (5 : undefined)) (Just 5)
+        it "returns Nothing for []" do
+            shouldBe @(Maybe Integer) (run first []) Nothing
+        it "is tenacious" do
+            shouldBe ((run ((,) <$> length <*> first)) "abc") (1, Just 'a')
+
+    describe "endpoint functions" do
+        describe "first" do
+            it "gets the first item" do
+                run first ([5, 4, 3] :: [Integer]) `shouldBe` Just 5
+            it "returns Nothing with no input" do
+                run first ([] :: [Integer]) `shouldBe` Nothing
+            it "is lazy" do
+                run first (5 : undefined :: [Integer]) `shouldBe` Just 5
+
+    describe "null" do
+        it "True for []" do
+            run null ([] :: [Integer]) `shouldBe` True
+        it "False for anything else" do
+            run null ([1] :: [Integer]) `shouldBe` False
+            run null ([1,2] :: [Integer]) `shouldBe` False
+            run null ([1,2,3] :: [Integer]) `shouldBe` False
+
+    describe "and" do
+        it "True for []" do
+            run and [] `shouldBe` True
+        it "True for [True, ...]" do
+            run and [True] `shouldBe` True
+            run and [True,True] `shouldBe` True
+            run and [True,True,True] `shouldBe` True
+        it "False for anything else" do
+            run and [False] `shouldBe` False
+            run and [False,True] `shouldBe` False
+            run and [True,False] `shouldBe` False
+        it "is lazy" do
+            run and (False : undefined) `shouldBe` False
+
+    describe "or" do
+        it "False for []" do
+            run or [] `shouldBe` False
+        it "False for [False, ...]" do
+            run or [False] `shouldBe` False
+            run or [False,False] `shouldBe` False
+            run or [False,False,False] `shouldBe` False
+        it "True for anything else" do
+            run or [True] `shouldBe` True
+            run or [False,True] `shouldBe` True
+            run or [True,False] `shouldBe` True
+        it "is lazy" do
+            run or (True : undefined) `shouldBe` True
diff --git a/test/Spec/ShortcutNonempty.hs b/test/Spec/ShortcutNonempty.hs
new file mode 100644
--- /dev/null
+++ b/test/Spec/ShortcutNonempty.hs
@@ -0,0 +1,59 @@
+module Spec.ShortcutNonempty where
+
+import Fold.ShortcutNonempty
+
+import Test.Hspec
+
+import Control.Applicative (pure, (<$>), (<*>))
+import Prelude (Integer, undefined)
+import Data.List.NonEmpty (NonEmpty ((:|)))
+import Data.Maybe (Maybe (Just))
+import Data.Bool (Bool (..))
+import Data.List ((++))
+
+import qualified Data.Char as Char
+
+spec :: SpecWith ()
+spec = describe "ShortcutNonemptyFold" do
+
+    it "Applicative" do
+        let x = do
+                  a <- length
+                  b <- find Char.isLetter
+                  c <- elementIndex 'x'
+                  d <- elementIndex 'y'
+                  e <- last
+                  pure (a, b, c, d, e)
+        run x ('1' :| "234xyz" ++ undefined) `shouldBe` (6, Just 'x', Just 4, Just 5, 'y')
+
+    describe "first" do
+        it "gets the first item" do
+            shouldBe @Integer (run first [5, 4, 3]) 5
+        it "is lazy" do
+            shouldBe @Integer (run first (5 :| undefined)) 5
+        it "is tenacious" do
+            shouldBe ((run ((,) <$> length <*> first)) ('a' :| "bc")) (1, 'a')
+
+    describe "and" do
+        it "True for [True, ...]" do
+            run and [True] `shouldBe` True
+            run and [True,True] `shouldBe` True
+            run and [True,True,True] `shouldBe` True
+        it "False for anything else" do
+            run and [False] `shouldBe` False
+            run and [False,True] `shouldBe` False
+            run and [True,False] `shouldBe` False
+        it "is lazy" do
+            run and (False :| undefined) `shouldBe` False
+
+    describe "or" do
+        it "False for [False, ...]" do
+            run or [False] `shouldBe` False
+            run or [False,False] `shouldBe` False
+            run or [False,False,False] `shouldBe` False
+        it "True for anything else" do
+            run or [True] `shouldBe` True
+            run or [False,True] `shouldBe` True
+            run or [True,False] `shouldBe` True
+        it "is lazy" do
+            run or (True :| undefined) `shouldBe` True
