diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+1.4.5
+
+* Increase upper bound on `containers`
+* Add `either`/`eitherM`
+
 1.4.4
 
 * Increase lower bound on `base`
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# `foldl` v1.4.4
+# `foldl` v1.4.5
 
 Use this `foldl` library when you want to compute multiple folds over a
 collection in one pass over the data without space leaks.
diff --git a/foldl.cabal b/foldl.cabal
--- a/foldl.cabal
+++ b/foldl.cabal
@@ -1,5 +1,5 @@
 Name: foldl
-Version: 1.4.4
+Version: 1.4.5
 Cabal-Version: >=1.8.0.2
 Build-Type: Simple
 License: BSD3
@@ -31,7 +31,7 @@
         text         >= 0.11.2.0 && < 1.3 ,
         transformers >= 0.2.0.0  && < 0.6 ,
         vector       >= 0.7      && < 0.13,
-        containers   >= 0.5.0.0  && < 0.6 ,
+        containers   >= 0.5.0.0  && < 0.7 ,
         unordered-containers        < 0.3 ,
         hashable                    < 1.3 ,
         contravariant               < 1.6 ,
@@ -46,6 +46,7 @@
         Control.Foldl.Text,
         Control.Scanl
     Other-Modules:
+        Control.Foldl.Optics
         Control.Foldl.Internal
     GHC-Options: -O2 -Wall
 
diff --git a/src/Control/Foldl.hs b/src/Control/Foldl.hs
--- a/src/Control/Foldl.hs
+++ b/src/Control/Foldl.hs
@@ -128,6 +128,8 @@
     , folded
     , filtered
     , groupBy
+    , either
+    , eitherM
 
     -- * Re-exports
     -- $reexports
@@ -136,6 +138,7 @@
     , module Data.Vector.Generic
     ) where
 
+import Control.Foldl.Optics (_Left, _Right)
 import Control.Applicative
 import Control.Foldl.Internal (Maybe'(..), lazy, Either'(..), Pair(..), hush)
 import Control.Monad ((<=<))
@@ -173,6 +176,7 @@
     , notElem
     , lookup
     , map
+    , either
     )
 
 import qualified Data.Foldable               as F
@@ -1323,6 +1327,18 @@
   where
     f' !m !a = alter (\o -> Just (f (fromMaybe i o) a)) (grouper a) m
 {-# INLINABLE groupBy #-}
+
+{-| Combine two folds into a fold over inputs for either of them.
+-}
+either :: Fold a1 b1 -> Fold a2 b2 -> Fold (Either a1 a2) (b1, b2)
+either l r = (,) <$> handles _Left l <*> handles _Right r
+{-# INLINABLE either #-}
+
+{-| Combine two monadic folds into a fold over inputs for either of them.
+-}
+eitherM :: Monad m => FoldM m a1 b1 -> FoldM m a2 b2 -> FoldM m (Either a1 a2) (b1, b2)
+eitherM l r = (,) <$> handlesM _Left l <*> handlesM _Right r
+{-# INLINABLE eitherM #-}
 
 {- $reexports
     @Control.Monad.Primitive@ re-exports the 'PrimMonad' type class
diff --git a/src/Control/Foldl/Optics.hs b/src/Control/Foldl/Optics.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Foldl/Optics.hs
@@ -0,0 +1,21 @@
+{-# LANGUAGE RankNTypes #-}
+module Control.Foldl.Optics where
+
+import Data.Profunctor
+import Control.Applicative
+
+type Prism s t a b = forall p f. (Choice p, Applicative f) => p a (f b) -> p s (f t)
+
+type Prism' s a = Prism s s a a
+
+prism :: (b -> t) -> (s -> Either t a) -> Prism s t a b
+prism bt seta = dimap seta (either pure (fmap bt)) . right'
+{-# INLINE prism #-}
+
+_Left :: Prism (Either a c) (Either b c) a b
+_Left = prism Left $ either Right (Left . Right)
+{-# INLINE _Left #-}
+
+_Right :: Prism (Either c a) (Either c b) a b
+_Right = prism Right $ either (Left . Left) Right
+{-# INLINE _Right #-}
