diff --git a/errors-ext.cabal b/errors-ext.cabal
--- a/errors-ext.cabal
+++ b/errors-ext.cabal
@@ -1,47 +1,67 @@
-name: errors-ext
-version: 0.4.1
-synopsis: `bracket`-like functions for `ExceptT` over `IO` monad.
-description: `bracket`-like functions for `ExceptT` over `IO` monad.
-homepage: https://github.com/A1-Triard/errors-ext#readme
-license: Apache
-license-file: LICENSE
-author: Warlock <internalmike@gmail.com>
-maintainer: Warlock <internalmike@gmail.com>
-copyright: 2017 Warlock <internalmike@gmail.com>
-category: Control, Error Handling
-build-type: Simple
--- extra-source-files:
-cabal-version: >=1.10
+-- This file has been generated from package.yaml by hpack version 0.28.2.
+--
+-- see: https://github.com/sol/hpack
+--
+-- hash: 81ddf04aa29463fe76044d3296fe782c805664465d860021824bb5250ebc18e3
 
+name:           errors-ext
+version:        0.4.2
+synopsis:       `bracket`-like functions for `ExceptT` over `IO` monad.
+description:    Please see the README on GitHub at <https://github.com/A1-Triard/errors-ext#readme>
+category:       Control, Error Handling
+homepage:       https://github.com/A1-Triard/errors-ext#readme
+bug-reports:    https://github.com/A1-Triard/errors-ext/issues
+author:         Warlock <internalmike@gmail.com>
+maintainer:     Warlock <internalmike@gmail.com>
+copyright:      2017, 2018 Warlock <internalmike@gmail.com>
+license:        Apache
+license-file:   LICENSE
+build-type:     Simple
+cabal-version:  >= 1.10
+
+source-repository head
+  type: git
+  location: https://github.com/A1-Triard/errors-ext
+
 library
-  hs-source-dirs: src
-  exposed-modules: Control.Error.Extensions
+  exposed-modules:
+      Control.Error.Extensions
+  other-modules:
+      Paths_errors_ext
+  hs-source-dirs:
+      src
   default-extensions: FlexibleContexts
-  ghc-options: -fmax-pmcheck-iterations=100000000 -Wall -fprint-potential-instances
-  build-depends: base >= 4.7 && < 5
-               , errors
-               , exceptions
-               , monad-control
-               , mtl
-               , transformers
+  ghc-options: -fmax-pmcheck-iterations=100000000 -Wall -fprint-potential-instances -fsimpl-tick-factor=110
+  build-depends:
+      base >=4.7 && <5
+    , errors
+    , exceptions
+    , monad-control
+    , mtl
+    , transformers
   default-language: Haskell2010
 
 test-suite errors-ext-test
   type: exitcode-stdio-1.0
-  hs-source-dirs: test
   main-is: Spec.hs
-  other-modules: Control.Error.Extensions.Spec
-  ghc-options: -threaded -rtsopts -with-rtsopts=-N -fmax-pmcheck-iterations=100000000 -Wall -fprint-potential-instances
-  build-depends: base
-               , HUnit
-               , errors-ext
-               , errors
-               , exceptions
-               , monad-control
-               , mtl
-               , transformers
+  other-modules:
+      Control.Error.Extensions.Spec
+      Paths_errors_ext
+  hs-source-dirs:
+      test
+  default-extensions: FlexibleContexts BangPatterns OverloadedStrings
+  ghc-options: -fmax-pmcheck-iterations=100000000 -Wall -fprint-potential-instances -fsimpl-tick-factor=110 -threaded -rtsopts -with-rtsopts=-N
+  build-depends:
+      HUnit
+    , base >=4.7 && <5
+    , binary-ext >=2.0.4
+    , bytestring
+    , conduit
+    , errors
+    , errors-ext
+    , exceptions
+    , monad-control
+    , monad-loops
+    , mtl
+    , transformers
   default-language: Haskell2010
-
-source-repository head
-  type: git
-  location: https://github.com/A1-Triard/errors-ext
diff --git a/src/Control/Error/Extensions.hs b/src/Control/Error/Extensions.hs
--- a/src/Control/Error/Extensions.hs
+++ b/src/Control/Error/Extensions.hs
@@ -1,5 +1,5 @@
 --
--- Copyright 2017 Warlock <internalmike@gmail.com>
+-- Copyright 2017, 2018 Warlock <internalmike@gmail.com>
 --
 -- Licensed under the Apache License, Version 2.0 (the "License");
 -- you may not use this file except in compliance with the License.
@@ -19,6 +19,10 @@
 module Control.Error.Extensions
   ( bracketE
   , bracketE_
+  , eitherMaybe
+  , maybeEither
+  , eitherVoidL
+  , eitherVoidR
   ) where
 
 import Control.Exception
@@ -28,6 +32,7 @@
 import Control.Monad.Error.Class
 import Control.Monad.Trans.Control
 import Control.Monad.Trans.Except ()
+import Data.Void
 
 liftedBracketOnError :: MonadBaseControl IO m => m a -> (a -> m b) -> (a -> m c) -> m c
 liftedBracketOnError acquire release action = control $ \run ->
@@ -71,3 +76,28 @@
 bracketE_ :: (MonadBaseControl IO m, MonadError e m) => m a -> m b -> m c -> m c
 bracketE_ acquire release action = bracketE acquire (const release) (const action)
 {-# INLINE bracketE_ #-}
+
+-- | Converts 'Maybe' to 'Either'. Specialization of 'maybe'.
+--
+-- @maybeEither . 'eitherMaybe' = 'id'@
+maybeEither :: Maybe a -> Either () a
+maybeEither = maybe (Left ()) Right
+{-# INLINE maybeEither #-}
+
+-- | Converts 'Either' to 'Maybe'. Specialization of 'either'.
+--
+-- @'maybeEither' . eitherMaybe = 'id'@
+eitherMaybe :: Either () a -> Maybe a
+eitherMaybe = either (const Nothing) Just
+{-# INLINE eitherMaybe #-}
+
+
+-- | Removes right zero term from sum type. Specialization of 'either'.
+eitherVoidR :: Either a Void -> a
+eitherVoidR = either id absurd
+{-# INLINE eitherVoidR #-}
+
+-- | Removes left zero term from sum type. Specialization of 'either'.
+eitherVoidL :: Either Void a -> a
+eitherVoidL = either absurd id
+{-# INLINE eitherVoidL #-}
diff --git a/test/Control/Error/Extensions/Spec.hs b/test/Control/Error/Extensions/Spec.hs
--- a/test/Control/Error/Extensions/Spec.hs
+++ b/test/Control/Error/Extensions/Spec.hs
@@ -1,5 +1,5 @@
 --
--- Copyright 2017 Warlock <internalmike@gmail.com>
+-- Copyright 2017, 2018 Warlock <internalmike@gmail.com>
 --
 -- Licensed under the Apache License, Version 2.0 (the "License");
 -- you may not use this file except in compliance with the License.
@@ -21,13 +21,23 @@
 import Test.HUnit.Base hiding (Label)
 import Control.Error.Extensions
 import Control.Exception
+import Control.Monad.Error.Class
+import Control.Monad.Loops
 import Control.Monad.Trans.Class
 import Control.Monad.Trans.Except
+import qualified Data.ByteString as S (ByteString)
+import Data.Conduit hiding (ConduitM)
+import qualified Data.Conduit.Combinators as N
+import Data.Conduit.Lift
+import Data.Conduit.Parsers.Binary.Get
+import Data.Conduit.Parsers.Binary.Put
 import Data.IORef
 import System.IO.Error
 
 tests :: Test
-tests = TestList $ (TestCase . runBracketTest) <$> bracketTests
+tests = TestList
+  $  ((TestCase . runBracketTest) <$> bracketTests)
+  ++ [TestCase testPrevNaturalsFile]
 
 data Resource = Resource { acquired :: !Bool, released :: !Bool, processed :: !Bool } deriving (Eq, Show)
 
@@ -72,34 +82,50 @@
 processEr :: Process
 processEr _ = throwE "processEr"
 
-data Error = Error { isException :: !Bool, message :: !String } deriving (Eq, Show)
+data Err = Err { isException :: !Bool, message :: !String } deriving (Eq, Show)
 
-bracketTest :: Acquire -> Release -> Process -> IO (Resource, Either Error Resource)
+bracketTest :: Acquire -> Release -> Process -> IO (Resource, Either Err Resource)
 bracketTest acquire release process = do
   r <- resource
-  p <- catch (either (\x -> Left $ Error False x) Right <$> (runExceptT $ bracketE (acquire r) release process)) $ \e ->
-    let _ = e :: IOError in return $ Left $ Error True $ ioeGetErrorString e
+  p <- catch (either (\x -> Left $ Err False x) Right <$> (runExceptT $ bracketE (acquire r) release process)) $ \e ->
+    let _ = e :: IOError in return $ Left $ Err True $ ioeGetErrorString e
   f <- readIORef r
   return (f, p)
 
-data TestData = TestData String !Acquire !Release !Process !(Resource, Either Error Resource)
+data TestData = TestData String !Acquire !Release !Process !(Resource, Either Err Resource)
 
 bracketTests :: [TestData]
 bracketTests =
   [ TestData "1" acquireOk releaseOk processOk (Resource True True True, Right $ Resource True False False)
-  , TestData "2" acquireEx releaseOk processOk (Resource False False False, Left $ Error { isException = True, message = "acquireEx" })
-  , TestData "3" acquireEr releaseOk processOk (Resource False False False, Left $ Error { isException = False, message = "acquireEr" })
-  , TestData "4" acquireOk releaseEx processOk (Resource True False True, Left $ Error { isException = True, message = "releaseEx" })
-  , TestData "5" acquireOk releaseEr processOk (Resource True False True, Left $ Error { isException = False, message = "releaseEr" })
-  , TestData "6" acquireOk releaseOk processEx (Resource True True False, Left $ Error { isException = True, message = "processEx" })
-  , TestData "7" acquireOk releaseOk processEr (Resource True True False, Left $ Error { isException = False, message = "processEr" })
-  , TestData "8" acquireOk releaseEx processEx (Resource True False False, Left $ Error { isException = True, message = "processEx" })
-  , TestData "9" acquireOk releaseEr processEx (Resource True False False, Left $ Error { isException = True, message = "processEx" })
-  , TestData "10" acquireOk releaseEx processEr (Resource True False False, Left $ Error { isException = False, message = "processEr" })
-  , TestData "11" acquireOk releaseEr processEr (Resource True False False, Left $ Error { isException = False, message = "processEr" })
+  , TestData "2" acquireEx releaseOk processOk (Resource False False False, Left $ Err { isException = True, message = "acquireEx" })
+  , TestData "3" acquireEr releaseOk processOk (Resource False False False, Left $ Err { isException = False, message = "acquireEr" })
+  , TestData "4" acquireOk releaseEx processOk (Resource True False True, Left $ Err { isException = True, message = "releaseEx" })
+  , TestData "5" acquireOk releaseEr processOk (Resource True False True, Left $ Err { isException = False, message = "releaseEr" })
+  , TestData "6" acquireOk releaseOk processEx (Resource True True False, Left $ Err { isException = True, message = "processEx" })
+  , TestData "7" acquireOk releaseOk processEr (Resource True True False, Left $ Err { isException = False, message = "processEr" })
+  , TestData "8" acquireOk releaseEx processEx (Resource True False False, Left $ Err { isException = True, message = "processEx" })
+  , TestData "9" acquireOk releaseEr processEx (Resource True False False, Left $ Err { isException = True, message = "processEx" })
+  , TestData "10" acquireOk releaseEx processEr (Resource True False False, Left $ Err { isException = False, message = "processEr" })
+  , TestData "11" acquireOk releaseEr processEr (Resource True False False, Left $ Err { isException = False, message = "processEr" })
   ]
 
 runBracketTest :: TestData -> Assertion
 runBracketTest (TestData m a r p e) = do
   t <- bracketTest a r p
   assertEqual m e t
+
+data PrevNaturalError = NotNatural Integer | Minimal deriving (Eq, Show)
+
+prevNatural :: (Monad m, Integral i) => ConduitT i i (ExceptT PrevNaturalError m) ()
+prevNatural = awaitForever $ \ !n -> do
+  if n <= 0 then throwError (NotNatural $ fromIntegral n) else return ()
+  if n == 1 then throwError Minimal else return ()
+  yield $ n - 1
+
+prevNaturalsFile :: Monad m => ConduitT S.ByteString S.ByteString (ExceptT PrevNaturalError m) ()
+prevNaturalsFile = (eitherVoidR <$> runGet (iterateM_ (const $ yield =<< getInt8) (error ""))) .| prevNatural .| awaitForever (runPut . putInt8)
+
+testPrevNaturalsFile :: Assertion
+testPrevNaturalsFile = do
+  assertEqual "" (Left Minimal, "") $ runConduitPure $ yield "\x01\x02\x03" .| runExceptC prevNaturalsFile `fuseBoth` N.sinkLazy
+  assertEqual "" (Right (), "\x02\x07\x08") $ runConduitPure $ yield "\x03\x08\x09" .| runExceptC prevNaturalsFile `fuseBoth` N.sinkLazy
