diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,7 @@
+# 0.1.1.0
+
+- Adds a `runNonDetOnce` handler which terminates immediately upon finding a solution.
+
 # 0.1.0.0
 
 Initial release.
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
 
 - [Overview](#overview)
   - [Algebraic effects](#algebraic-effects)
-  - [Higher-order effects](#fused-effects)
+  - [Higher-order effects](#higher-order-effects)
   - [Fusion](#fusion)
 - [Usage](#usage)
   - [Using built-in effects](#using-built-in-effects)
@@ -19,7 +19,7 @@
 
 ## Overview
 
-`fused-effects` is an effect system for Haskell emphasizing expressivity and efficiency. The former is achieved by encoding [algebraic](#algebraic-effects), [higher-order](#fused-effects) effects, while the latter is the result of [fusing](#fusion) effect handlers all the way through computations.
+`fused-effects` is an effect system for Haskell emphasizing expressivity and efficiency. The former is achieved by encoding [algebraic](#algebraic-effects), [higher-order](#higher-order-effects) effects, while the latter is the result of [fusing](#fusion) effect handlers all the way through computations.
 
 Readers already familiar with effect systems may wish to start with the [usage](#usage) instead.
 
diff --git a/fused-effects.cabal b/fused-effects.cabal
--- a/fused-effects.cabal
+++ b/fused-effects.cabal
@@ -1,5 +1,5 @@
 name:                fused-effects
-version:             0.1.0.0
+version:             0.1.1.0
 synopsis:            A fast, flexible, fused effect system.
 description:         A fast, flexible, fused effect system, à la Effect Handlers in Scope, Monad Transformers and Modular Algebraic Effects: What Binds Them Together, and Fusion for Free—Efficient Algebraic Effect Handlers.
 homepage:            https://github.com/robrix/fused-effects
diff --git a/src/Control/Effect.hs b/src/Control/Effect.hs
--- a/src/Control/Effect.hs
+++ b/src/Control/Effect.hs
@@ -8,7 +8,7 @@
 import Control.Effect.Fresh     as X (Fresh, FreshC)
 import Control.Effect.Internal  as X (Eff, interpret)
 import Control.Effect.Lift      as X (Lift, LiftC, runM)
-import Control.Effect.NonDet    as X (NonDet, AltC)
+import Control.Effect.NonDet    as X (NonDet, AltC, OnceC)
 import Control.Effect.Random    as X (Random, RandomC)
 import Control.Effect.Reader    as X (Reader, ReaderC)
 import Control.Effect.Resource  as X (Resource, ResourceC)
diff --git a/src/Control/Effect/NonDet.hs b/src/Control/Effect/NonDet.hs
--- a/src/Control/Effect/NonDet.hs
+++ b/src/Control/Effect/NonDet.hs
@@ -4,6 +4,8 @@
 , Alternative(..)
 , runNonDet
 , AltC(..)
+, runNonDetOnce
+, OnceC(..)
 ) where
 
 import Control.Applicative (Alternative(..), liftA2)
@@ -14,7 +16,7 @@
 
 -- | Run a 'NonDet' effect, collecting all branches’ results into an 'Alternative' functor.
 --
---   Using '[]' as the 'Alternative' functor will produce all results, while 'Maybe' will return only the first.
+--   Using '[]' as the 'Alternative' functor will produce all results, while 'Maybe' will return only the first. However, unlike 'runNonDetOnce', this will still enumerate the entire search space before returning, meaning that it will diverge for infinite search spaces, even when using 'Maybe'.
 --
 --   prop> run (runNonDet (pure a)) == [a]
 --   prop> run (runNonDet (pure a)) == Just a
@@ -30,7 +32,31 @@
     Choose k -> liftA2 (<|>) (runAltC (k True)) (runAltC (k False)))
 
 
+-- | Run a 'NonDet' effect, returning the first successful result in an 'Alternative' functor.
+--
+--   Unlike 'runNonDet', this will terminate immediately upon finding a solution.
+--
+--   prop> run (runNonDetOnce (asum (map pure (repeat a)))) == [a]
+--   prop> run (runNonDetOnce (asum (map pure (repeat a)))) == Just a
+runNonDetOnce :: (Alternative f, Monad f, Traversable f, Carrier sig m, Effect sig, Monad m) => Eff (OnceC f m) a -> m (f a)
+runNonDetOnce = runOnceC . interpret
+
+newtype OnceC f m a = OnceC { runOnceC :: m (f a) }
+
+instance (Alternative f, Monad f, Traversable f, Carrier sig m, Effect sig, Monad m) => Carrier (NonDet :+: sig) (OnceC f m) where
+  ret a = OnceC (ret (pure a))
+  eff = OnceC . handleSum (eff . handleTraversable runOnceC) (\case
+    Empty    -> ret empty
+    Choose k -> do
+      l <- runOnceC (k True)
+      if null l then
+        runOnceC (k False)
+      else
+        pure l)
+
+
 -- $setup
 -- >>> :seti -XFlexibleContexts
 -- >>> import Test.QuickCheck
 -- >>> import Control.Effect.Void
+-- >>> import Data.Foldable (asum)
