diff --git a/pipes-extras.cabal b/pipes-extras.cabal
--- a/pipes-extras.cabal
+++ b/pipes-extras.cabal
@@ -1,5 +1,5 @@
 Name: pipes-extras
-Version: 1.0.10
+Version: 1.0.11
 Cabal-Version: >=1.10
 Build-Type: Simple
 License: BSD3
@@ -22,7 +22,8 @@
         base         >= 4       && < 5  ,
         pipes        >= 4.0     && < 4.4,
         foldl        >= 1.0.1   && < 1.4,
-        transformers >= 0.2.0.0 && < 0.6
+        transformers >= 0.2.0.0 && < 0.6,
+        lens         >= 4.3     && < 4.16
     Exposed-Modules: Pipes.Extras
     GHC-Options: -O2 -Wall
     Default-Language: Haskell2010
diff --git a/src/Pipes/Extras.hs b/src/Pipes/Extras.hs
--- a/src/Pipes/Extras.hs
+++ b/src/Pipes/Extras.hs
@@ -44,6 +44,7 @@
 import Pipes
 import Pipes.Core (request, respond, (>\\), (//>))
 import Pipes.Internal (Proxy(..))
+import Control.Lens (Prism, withPrism, _Left, _Right)
 import qualified Pipes.Prelude as Pipes
 
 -- | Like 'Control.Arrow.arr' from 'Control.Arrow.Arrow'
@@ -51,33 +52,33 @@
 arr = Pipes.map
 {-# INLINABLE arr #-}
 
--- | Like 'Control.Arrow.left' from 'Control.Arrow.ArrowChoice'
-left :: Monad m => Pipe a b m r -> Pipe (Either a x) (Either b x) m r
-left p = await' >~ for p yield'
-  where
-    yield' b = yield (Left b)
+select :: Monad m => (b -> t) -> (s -> Either t a) -> Pipe a b m r -> Pipe s t m r
+select inj proj pipe = await' >~ for pipe yield'
+    where
+    yield' b = yield (inj b)
     await' = do
-        e <- await
-        case e of
-            Left  a -> return a
-            Right x -> do
-                yield (Right x)
+        s <- await
+        case proj s of
+            Left t -> do
+                yield t 
                 await'
+            Right a -> return a
+{-# INLINABLE select #-}
+
+select' :: Monad m => Prism s t a b -> Pipe a b m r -> Pipe s t m r
+select' prism = withPrism prism select
+{-# INLINABLE select' #-}
+
+-- | Like 'Control.Arrow.left' from 'Control.Arrow.ArrowChoice'
+left :: Monad m => Pipe a b m r -> Pipe (Either a x) (Either b x) m r
+left = select' _Left
 {-# INLINABLE left #-}
 
 -- | Like 'Control.Arrow.right' from 'Control.Arrow.ArrowChoice'
 right :: Monad m => Pipe a b m r -> Pipe (Either x a) (Either x b) m r
-right p = await' >~ for p yield'
-  where
-    yield' b = yield (Right b)
-    await' = do
-        e <- await
-        case e of
-            Left  x -> do
-                yield (Left x)
-                await'
-            Right a -> return a
+right = select' _Right
 {-# INLINABLE right #-}
+
 
 {-| Like ('Control.Arrow.+++') from 'Control.Arrow.ArrowChoice'
 
