diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,24 +1,24 @@
-Copyright (c) 2013 Gabriel Gonzalez
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
-    * Redistributions of source code must retain the above copyright notice,
-      this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above copyright notice,
-      this list of conditions and the following disclaimer in the documentation
-      and/or other materials provided with the distribution.
-    * Neither the name of Gabriel Gonzalez nor the names of other contributors
-      may be used to endorse or promote products derived from this software
-      without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+Copyright (c) 2013 Gabriel Gonzalez
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+    * Neither the name of Gabriel Gonzalez nor the names of other contributors
+      may be used to endorse or promote products derived from this software
+      without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Setup.hs b/Setup.hs
--- a/Setup.hs
+++ b/Setup.hs
@@ -1,2 +1,2 @@
-import Distribution.Simple
-main = defaultMain
+import Distribution.Simple
+main = defaultMain
diff --git a/foldl.cabal b/foldl.cabal
--- a/foldl.cabal
+++ b/foldl.cabal
@@ -1,37 +1,37 @@
-Name: foldl
-Version: 1.0.8
-Cabal-Version: >=1.8.0.2
-Build-Type: Simple
-License: BSD3
-License-File: LICENSE
-Copyright: 2013 Gabriel Gonzalez
-Author: Gabriel Gonzalez
-Maintainer: Gabriel439@gmail.com
-Bug-Reports: https://github.com/Gabriel439/Haskell-Foldl-Library/issues
-Synopsis: Composable, streaming, and efficient left folds
-Description: This library provides strict left folds that stream in constant
-  memory, and you can combine folds using @Applicative@ style to derive new
-  folds.  Derived folds still traverse the container just once and are often as
-  efficient as hand-written folds.
-Category: Control
-Source-Repository head
-    Type: git
-    Location: https://github.com/Gabriel439/Haskell-Foldl-Library
-
-Library
-    HS-Source-Dirs: src
-    Build-Depends:
-        base         >= 4        && < 5   ,
-        bytestring   >= 0.9.2.1  && < 0.11,
-        primitive                   < 0.6 ,
-        text         >= 0.11.2.0 && < 1.3 ,
-        transformers >= 0.2.0.0  && < 0.5 ,
-        vector       >= 0.7      && < 0.11,
-        containers                  < 0.6
-    Exposed-Modules:
-        Control.Foldl,
-        Control.Foldl.ByteString,
-        Control.Foldl.Text
-    Other-Modules:
-        Control.Foldl.Internal
-    GHC-Options: -O2 -Wall
+Name: foldl
+Version: 1.0.9
+Cabal-Version: >=1.8.0.2
+Build-Type: Simple
+License: BSD3
+License-File: LICENSE
+Copyright: 2013 Gabriel Gonzalez
+Author: Gabriel Gonzalez
+Maintainer: Gabriel439@gmail.com
+Bug-Reports: https://github.com/Gabriel439/Haskell-Foldl-Library/issues
+Synopsis: Composable, streaming, and efficient left folds
+Description: This library provides strict left folds that stream in constant
+  memory, and you can combine folds using @Applicative@ style to derive new
+  folds.  Derived folds still traverse the container just once and are often as
+  efficient as hand-written folds.
+Category: Control
+Source-Repository head
+    Type: git
+    Location: https://github.com/Gabriel439/Haskell-Foldl-Library
+
+Library
+    HS-Source-Dirs: src
+    Build-Depends:
+        base         >= 4        && < 5   ,
+        bytestring   >= 0.9.2.1  && < 0.11,
+        primitive                   < 0.7 ,
+        text         >= 0.11.2.0 && < 1.3 ,
+        transformers >= 0.2.0.0  && < 0.5 ,
+        vector       >= 0.7      && < 0.11,
+        containers                  < 0.6
+    Exposed-Modules:
+        Control.Foldl,
+        Control.Foldl.ByteString,
+        Control.Foldl.Text
+    Other-Modules:
+        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
@@ -1,805 +1,805 @@
-{-| This module provides efficient and streaming left folds that you can combine
-    using 'Applicative' style.
-
-    Import this module qualified to avoid clashing with the Prelude:
-
->>> import qualified Control.Foldl as L
-
-    Use 'fold' to apply a 'Fold' to a list:
-
->>> L.fold L.sum [1..100]
-5050
-
-    'Fold's are 'Applicative's, so you can combine them using 'Applicative'
-    combinators:
-
->>> import Control.Applicative
->>> let average = (/) <$> L.sum <*> L.genericLength
-
-    These combined folds will still traverse the list only once, streaming
-    efficiently over the list in constant space without space leaks:
-
->>> L.fold average [1..10000000]
-5000000.5
->>> L.fold ((,) <$> L.minimum <*> L.maximum) [1..10000000]
-(Just 1,Just 10000000)
-
--}
-
-{-# LANGUAGE ExistentialQuantification, RankNTypes, Trustworthy #-}
-
-module Control.Foldl (
-    -- * Fold Types
-      Fold(..)
-    , FoldM(..)
-
-    -- * Folding
-    , fold
-    , foldM
-    , scan
-
-    -- * Folds
-    , Control.Foldl.mconcat
-    , Control.Foldl.foldMap
-    , head
-    , last
-    , lastDef
-    , null
-    , length
-    , and
-    , or
-    , all
-    , any
-    , sum
-    , product
-    , maximum
-    , minimum
-    , elem
-    , notElem
-    , find
-    , index
-    , elemIndex
-    , findIndex
-
-    -- * Generic Folds
-    , genericLength
-    , genericIndex
-
-    -- * Container folds
-    , list
-    , revList
-    , nub
-    , eqNub
-    , set
-    , vector
-
-    -- * Utilities
-    -- $utilities
-    , purely
-    , impurely
-    , generalize
-    , simplify
-    , premap
-    , premapM
-    , pretraverse
-    , pretraverseM
-
-    -- * Re-exports
-    -- $reexports
-    , module Control.Monad.Primitive
-    , module Data.Foldable
-    , module Data.Vector.Generic
-    ) where
-
-import Control.Applicative (Applicative(pure, (<*>)),liftA2)
-import Control.Foldl.Internal (Maybe'(..), lazy, Either'(..), hush)
-import Control.Monad ((<=<))
-import Control.Monad.Primitive (PrimMonad)
-import Data.Foldable (Foldable)
-import qualified Data.Foldable as F
-import Data.Functor.Constant (Constant(Constant, getConstant))
-import Data.Functor.Identity (Identity, runIdentity)
-import Data.Monoid (Monoid(mempty, mappend), Endo(Endo, appEndo))
-import Data.Vector.Generic (Vector)
-import qualified Data.Vector.Generic as V
-import qualified Data.Vector.Generic.Mutable as M
-import qualified Data.List as List
-import qualified Data.Set as Set
-import Prelude hiding
-    ( head
-    , last
-    , null
-    , length
-    , and
-    , or
-    , all
-    , any
-    , sum
-    , product
-    , maximum
-    , minimum
-    , elem
-    , notElem
-    )
-
-{-| Efficient representation of a left fold that preserves the fold's step
-    function, initial accumulator, and extraction function
-
-    This allows the 'Applicative' instance to assemble derived folds that
-    traverse the container only once
-
-    A \''Fold' a b\' processes elements of type __a__ and results in a
-    value of type __b__.
--}
-data Fold a b
-  -- | @Fold @ @ step @ @ initial @ @ extract@
-  = forall x. Fold (x -> a -> x) x (x -> b)
-
-data Pair a b = Pair !a !b
-
-instance Functor (Fold a) where
-    fmap f (Fold step begin done) = Fold step begin (f . done)
-    {-# INLINABLE fmap #-}
-
-instance Applicative (Fold a) where
-    pure b    = Fold (\() _ -> ()) () (\() -> b)
-    {-# INLINABLE pure #-}
-
-    (Fold stepL beginL doneL) <*> (Fold stepR beginR doneR) =
-        let step (Pair xL xR) a = Pair (stepL xL a) (stepR xR a)
-            begin = Pair beginL beginR
-            done (Pair xL xR) = doneL xL (doneR xR)
-        in  Fold step begin done
-    {-# INLINABLE (<*>) #-}
-
-instance Monoid b => Monoid (Fold a b) where
-    mempty = pure mempty
-    {-# INLINABLE mempty #-}
-
-    mappend = liftA2 mappend
-    {-# INLINABLE mappend #-}
-
-instance Num b => Num (Fold a b) where
-    fromInteger = pure . fromInteger
-    {-# INLINABLE fromInteger #-}
-
-    negate = fmap negate
-    {-# INLINABLE negate #-}
-
-    abs = fmap abs
-    {-# INLINABLE abs #-}
-
-    signum = fmap signum
-    {-# INLINABLE signum #-}
-
-    (+) = liftA2 (+)
-    {-# INLINABLE (+) #-}
-
-    (*) = liftA2 (*)
-    {-# INLINABLE (*) #-}
-
-    (-) = liftA2 (-)
-    {-# INLINABLE (-) #-}
-
-instance Fractional b => Fractional (Fold a b) where
-    fromRational = pure . fromRational
-    {-# INLINABLE fromRational #-}
-
-    recip = fmap recip
-    {-# INLINABLE recip #-}
-
-    (/) = liftA2 (/)
-    {-# INLINABLE (/) #-}
-
-instance Floating b => Floating (Fold a b) where
-    pi = pure pi
-    {-# INLINABLE pi #-}
-
-    exp = fmap exp
-    {-# INLINABLE exp #-}
-
-    sqrt = fmap sqrt
-    {-# INLINABLE sqrt #-}
-
-    log = fmap log
-    {-# INLINABLE log #-}
-
-    sin = fmap sin
-    {-# INLINABLE sin #-}
-
-    tan = fmap tan
-    {-# INLINABLE tan #-}
-
-    cos = fmap cos
-    {-# INLINABLE cos #-}
-
-    asin = fmap sin
-    {-# INLINABLE asin #-}
-
-    atan = fmap atan
-    {-# INLINABLE atan #-}
-
-    acos = fmap acos
-    {-# INLINABLE acos #-}
-
-    sinh = fmap sinh
-    {-# INLINABLE sinh #-}
-
-    tanh = fmap tanh
-    {-# INLINABLE tanh #-}
-
-    cosh = fmap cosh
-    {-# INLINABLE cosh #-}
-
-    asinh = fmap asinh
-    {-# INLINABLE asinh #-}
-
-    atanh = fmap atanh
-    {-# INLINABLE atanh #-}
-
-    acosh = fmap acosh
-    {-# INLINABLE acosh #-}
-
-    (**) = liftA2 (**)
-    {-# INLINABLE (**) #-}
-
-    logBase = liftA2 logBase
-    {-# INLINABLE logBase #-}
-
-{-| Like 'Fold', but monadic.
-
-    A \''FoldM' m a b\' processes elements of type __a__ and
-    results in a monadic value of type __m b__.
--}
-data FoldM m a b =
-  -- | @FoldM @ @ step @ @ initial @ @ extract@
-  forall x . FoldM (x -> a -> m x) (m x) (x -> m b)
-
-instance Monad m => Functor (FoldM m a) where
-    fmap f (FoldM step start done) = FoldM step start done'
-      where
-        done' x = do
-            b <- done x
-            return $! f b
-    {-# INLINABLE fmap #-}
-
-instance Monad m => Applicative (FoldM m a) where
-    pure b = FoldM (\() _ -> return ()) (return ()) (\() -> return b)
-    {-# INLINABLE pure #-}
-
-    (FoldM stepL beginL doneL) <*> (FoldM stepR beginR doneR) =
-        let step (Pair xL xR) a = do
-                xL' <- stepL xL a
-                xR' <- stepR xR a
-                return $! Pair xL' xR'
-            begin = do
-                xL <- beginL
-                xR <- beginR
-                return $! Pair xL xR
-            done (Pair xL xR) = do
-                f <- doneL xL
-                x <- doneR xR
-                return $! f x
-        in  FoldM step begin done
-    {-# INLINABLE (<*>) #-}
-
-instance (Monoid b, Monad m) => Monoid (FoldM m a b) where
-    mempty = pure mempty
-    {-# INLINABLE mempty #-}
-
-    mappend = liftA2 mappend
-    {-# INLINABLE mappend #-}
-
-instance (Monad m, Num b) => Num (FoldM m a b) where
-    fromInteger = pure . fromInteger
-    {-# INLINABLE fromInteger #-}
-
-    negate = fmap negate
-    {-# INLINABLE negate #-}
-
-    abs = fmap abs
-    {-# INLINABLE abs #-}
-
-    signum = fmap signum
-    {-# INLINABLE signum #-}
-
-    (+) = liftA2 (+)
-    {-# INLINABLE (+) #-}
-
-    (*) = liftA2 (*)
-    {-# INLINABLE (*) #-}
-
-    (-) = liftA2 (-)
-    {-# INLINABLE (-) #-}
-
-instance (Monad m, Fractional b) => Fractional (FoldM m a b) where
-    fromRational = pure . fromRational
-    {-# INLINABLE fromRational #-}
-
-    recip = fmap recip
-    {-# INLINABLE recip #-}
-
-    (/) = liftA2 (/)
-    {-# INLINABLE (/) #-}
-
-instance (Monad m, Floating b) => Floating (FoldM m a b) where
-    pi = pure pi
-    {-# INLINABLE pi #-}
-
-    exp = fmap exp
-    {-# INLINABLE exp #-}
-
-    sqrt = fmap sqrt
-    {-# INLINABLE sqrt #-}
-
-    log = fmap log
-    {-# INLINABLE log #-}
-
-    sin = fmap sin
-    {-# INLINABLE sin #-}
-
-    tan = fmap tan
-    {-# INLINABLE tan #-}
-
-    cos = fmap cos
-    {-# INLINABLE cos #-}
-
-    asin = fmap sin
-    {-# INLINABLE asin #-}
-
-    atan = fmap atan
-    {-# INLINABLE atan #-}
-
-    acos = fmap acos
-    {-# INLINABLE acos #-}
-
-    sinh = fmap sinh
-    {-# INLINABLE sinh #-}
-
-    tanh = fmap tanh
-    {-# INLINABLE tanh #-}
-
-    cosh = fmap cosh
-    {-# INLINABLE cosh #-}
-
-    asinh = fmap asinh
-    {-# INLINABLE asinh #-}
-
-    atanh = fmap atanh
-    {-# INLINABLE atanh #-}
-
-    acosh = fmap acosh
-    {-# INLINABLE acosh #-}
-
-    (**) = liftA2 (**)
-    {-# INLINABLE (**) #-}
-
-    logBase = liftA2 logBase
-    {-# INLINABLE logBase #-}
-
--- | Apply a strict left 'Fold' to a 'Foldable' container
-fold :: Foldable f => Fold a b -> f a -> b
-fold (Fold step begin done) as = F.foldr cons done as begin
-  where
-    cons a k x = k $! step x a
-{-# INLINE fold #-}
-
--- | Like 'fold', but monadic
-foldM :: (Foldable f, Monad m) => FoldM m a b -> f a -> m b
-foldM (FoldM step begin done) as0 = do
-    x0 <- begin
-    F.foldr step' done as0 $! x0
-  where
-    step' a k x = do
-        x' <- step x a
-        k $! x'
-{-# INLINE foldM #-}
-
--- | Convert a strict left 'Fold' into a scan
-scan :: Fold a b -> [a] -> [b]
-scan (Fold step begin done) as = foldr cons nil as begin
-  where
-    nil      x = done x:[]
-    cons a k x = done x:(k $! step x a)
-{-# INLINE scan #-}
-
--- | Fold all values within a container using 'mappend' and 'mempty'
-mconcat :: Monoid a => Fold a a
-mconcat = Fold mappend mempty id
-{-# INLINABLE mconcat #-}
-
--- | Convert a \"@foldMap@\" to a 'Fold'
-foldMap :: Monoid w => (a -> w) -> (w -> b) -> Fold a b
-foldMap to = Fold (\x a -> mappend x (to a)) mempty
-{-# INLINABLE foldMap #-}
-
-{-| Get the first element of a container or return 'Nothing' if the container is
-    empty
--}
-head :: Fold a (Maybe a)
-head = Fold step Nothing' lazy
-  where
-    step x a = case x of
-        Nothing' -> Just' a
-        _        -> x
-{-# INLINABLE head #-}
-
-{-| Get the last element of a container or return 'Nothing' if the container is
-    empty
--}
-last :: Fold a (Maybe a)
-last = Fold (const Just') Nothing' lazy
-{-# INLINABLE last #-}
-
-{-| Get the last element of a container or return a default value if the container
-    is empty
--}
-lastDef :: a -> Fold a a
-lastDef a = Fold (\_ a' -> a') a id
-{-# INLINABLE lastDef #-}
-
--- | Returns 'True' if the container is empty, 'False' otherwise
-null :: Fold a Bool
-null = Fold (\_ _ -> False) True id
-{-# INLINABLE null #-}
-
--- | Return the length of the container
-length :: Fold a Int
-length = genericLength
-{- Technically, 'length' is just 'genericLength' specialized to 'Int's.  I keep
-   the two separate so that I can later provide an 'Int'-specialized
-   implementation of 'length' for performance reasons like "GHC.List" does
-   without breaking backwards compatibility.
--}
-{-# INLINABLE length #-}
-
--- | Returns 'True' if all elements are 'True', 'False' otherwise
-and :: Fold Bool Bool
-and = Fold (&&) True id
-{-# INLINABLE and #-}
-
--- | Returns 'True' if any element is 'True', 'False' otherwise
-or :: Fold Bool Bool
-or = Fold (||) False id
-{-# INLINABLE or #-}
-
-{-| @(all predicate)@ returns 'True' if all elements satisfy the predicate,
-    'False' otherwise
--}
-all :: (a -> Bool) -> Fold a Bool
-all predicate = Fold (\x a -> x && predicate a) True id
-{-# INLINABLE all #-}
-
-{-| @(any predicate)@ returns 'True' if any element satisfies the predicate,
-    'False' otherwise
--}
-any :: (a -> Bool) -> Fold a Bool
-any predicate = Fold (\x a -> x || predicate a) False id
-{-# INLINABLE any #-}
-
--- | Computes the sum of all elements
-sum :: Num a => Fold a a
-sum = Fold (+) 0 id
-{-# INLINABLE sum #-}
-
--- | Computes the product all elements
-product :: Num a => Fold a a
-product = Fold (*) 1 id
-{-# INLINABLE product #-}
-
--- | Computes the maximum element
-maximum :: Ord a => Fold a (Maybe a)
-maximum = Fold step Nothing' lazy
-  where
-    step x a = Just' (case x of
-        Nothing' -> a
-        Just' a' -> max a' a)
-{-# INLINABLE maximum #-}
-
--- | Computes the minimum element
-minimum :: Ord a => Fold a (Maybe a)
-minimum = Fold step Nothing' lazy
-  where
-    step x a = Just' (case x of
-        Nothing' -> a
-        Just' a' -> min a' a)
-{-# INLINABLE minimum #-}
-
-{-| @(elem a)@ returns 'True' if the container has an element equal to @a@,
-    'False' otherwise
--}
-elem :: Eq a => a -> Fold a Bool
-elem a = any (a ==)
-{-# INLINABLE elem #-}
-
-{-| @(notElem a)@ returns 'False' if the container has an element equal to @a@,
-    'True' otherwise
--}
-notElem :: Eq a => a -> Fold a Bool
-notElem a = all (a /=)
-{-# INLINABLE notElem #-}
-
-{-| @(find predicate)@ returns the first element that satisfies the predicate or
-    'Nothing' if no element satisfies the predicate
--}
-find :: (a -> Bool) -> Fold a (Maybe a)
-find predicate = Fold step Nothing' lazy
-  where
-    step x a = case x of
-        Nothing' -> if predicate a then Just' a else Nothing'
-        _        -> x
-{-# INLINABLE find #-}
-
-{-| @(index n)@ returns the @n@th element of the container, or 'Nothing' if the
-    container has an insufficient number of elements
--}
-index :: Int -> Fold a (Maybe a)
-index = genericIndex
-{-# INLINABLE index #-}
-
-{-| @(elemIndex a)@ returns the index of the first element that equals @a@, or
-    'Nothing' if no element matches
--}
-elemIndex :: Eq a => a -> Fold a (Maybe Int)
-elemIndex a = findIndex (a ==)
-{-# INLINABLE elemIndex #-}
-
-{-| @(findIndex predicate)@ returns the index of the first element that
-    satisfies the predicate, or 'Nothing' if no element satisfies the predicate
--}
-findIndex :: (a -> Bool) -> Fold a (Maybe Int)
-findIndex predicate = Fold step (Left' 0) hush
-  where
-    step x a = case x of
-        Left' i ->
-            if predicate a
-            then Right' i
-            else Left' (i + 1)
-        _       -> x
-{-# INLINABLE findIndex #-}
-
--- | Like 'length', except with a more general 'Num' return value
-genericLength :: Num b => Fold a b
-genericLength = Fold (\n _ -> n + 1) 0 id
-{-# INLINABLE genericLength #-}
-
--- | Like 'index', except with a more general 'Integral' argument
-genericIndex :: Integral i => i -> Fold a (Maybe a)
-genericIndex i = Fold step (Left' 0) done
-  where
-    step x a = case x of
-        Left'  j -> if i == j then Right' a else Left' (j + 1)
-        _        -> x
-    done x = case x of
-        Left'  _ -> Nothing
-        Right' a -> Just a
-{-# INLINABLE genericIndex #-}
-
--- | Fold all values into a list
-list :: Fold a [a]
-list = Fold (\x a -> x . (a:)) id ($ [])
-{-# INLINABLE list #-}
-
--- | Fold all values into a list, in reverse order
-revList :: Fold a [a]
-revList = Fold (\x a -> a:x) [] id
-{-# INLINABLE revList #-}
-
-{-| /O(n log n)/.  Fold values into a list with duplicates removed, while
-    preserving their first occurrences
--}
-nub :: Ord a => Fold a [a]
-nub = Fold step (Pair Set.empty id) fin
-  where
-    step (Pair s r) a = if Set.member a s
-      then Pair s r
-      else Pair (Set.insert a s) (r . (a :))
-    fin (Pair _ r) = r []
-{-# INLINABLE nub #-}
-
-{-| /O(n^2)/.  Fold values into a list with duplicates removed, while preserving
-    their first occurrences
--}
-eqNub :: Eq a => Fold a [a]
-eqNub = Fold step (Pair [] id) fin
-  where
-    step (Pair known r) a = if List.elem a known
-      then Pair known r
-      else Pair (a : known) (r . (a :))
-    fin (Pair _ r) = r []
-{-# INLINABLE eqNub #-}
-
--- | Fold values into a set
-set :: Ord a => Fold a (Set.Set a)
-set = Fold (flip Set.insert) Set.empty id
-{-# INLINABLE set #-}
-
-maxChunkSize :: Int
-maxChunkSize = 8 * 1024 * 1024
-
--- | Fold all values into a vector
-vector :: (PrimMonad m, Vector v a) => FoldM m a (v a)
-vector = FoldM step begin done
-  where
-    begin = do
-        mv <- M.unsafeNew 10
-        return (Pair mv 0)
-    step (Pair mv idx) a = do
-        let len = M.length mv
-        mv' <- if idx >= len
-            then M.unsafeGrow mv (min len maxChunkSize)
-            else return mv
-        M.unsafeWrite mv' idx a
-        return (Pair mv' (idx + 1))
-    done (Pair mv idx) = do
-        v <- V.unsafeFreeze mv
-        return (V.unsafeTake idx v)
-{-# INLINABLE vector #-}
-
-{- $utilities
-    'purely' and 'impurely' allow you to write folds compatible with the @foldl@
-    library without incurring a @foldl@ dependency.  Write your fold to accept
-    three parameters corresponding to the step function, initial
-    accumulator, and extraction function and then users can upgrade your
-    function to accept a 'Fold' or 'FoldM' using the 'purely' or 'impurely'
-    combinators.
-
-    For example, the @pipes@ library implements a @foldM@ function in
-    @Pipes.Prelude@ with the following type:
-
-> foldM
->     :: Monad m
->     => (x -> a -> m x) -> m x -> (x -> m b) -> Producer a m () -> m b
-
-    @foldM@ is set up so that you can wrap it with 'impurely' to accept a
-    'FoldM' instead:
-
-> impurely foldM :: Monad m => FoldM m a b -> Producer a m () -> m b
--}
-
--- | Upgrade a fold to accept the 'Fold' type
-purely :: (forall x . (x -> a -> x) -> x -> (x -> b) -> r) -> Fold a b -> r
-purely f (Fold step begin done) = f step begin done
-{-# INLINABLE purely #-}
-
--- | Upgrade a monadic fold to accept the 'FoldM' type
-impurely
-    :: Monad m
-    => (forall x . (x -> a -> m x) -> m x -> (x -> m b) -> r)
-    -> FoldM m a b
-    -> r
-impurely f (FoldM step begin done) = f step begin done
-{-# INLINABLE impurely #-}
-
-{-| Generalize a `Fold` to a `FoldM`
-
-> generalize (pure r) = pure r
->
-> generalize (f <*> x) = generalize f <*> generalize x
--}
-generalize :: Monad m => Fold a b -> FoldM m a b
-generalize (Fold step begin done) = FoldM step' begin' done'
-  where
-    step' x a = return (step x a)
-    begin'    = return  begin
-    done' x   = return (done x)
-{-# INLINABLE generalize #-}
-
-{-| Simplify a pure `FoldM` to a `Fold`
-
-> simplify (pure r) = pure r
->
-> simplify (f <*> x) = simplify f <*> simplify x
--}
-simplify :: FoldM Identity a b -> Fold a b
-simplify (FoldM step begin done) = Fold step' begin' done'
-  where
-    step' x a = runIdentity (step x a)
-    begin'    = runIdentity  begin
-    done' x   = runIdentity (done x)
-{-# INLINABLE simplify #-}
-
-{-| @(premap f folder)@ returns a new 'Fold' where f is applied at each step
-
-> fold (premap f folder) list = fold folder (map f list)
-
->>> fold (premap Sum mconcat) [1..10]
-Sum {getSum = 55}
-
->>> fold mconcat (map Sum [1..10])
-Sum {getSum = 55}
-
-> premap id = id
->
-> premap (f . g) = premap g . premap f
-
-> premap k (pure r) = pure r
->
-> premap k (f <*> x) = premap k f <*> premap k x
--}
-premap :: (a -> b) -> Fold b r -> Fold a r
-premap f (Fold step begin done) = Fold step' begin done
-  where
-    step' x a = step x (f a)
-{-# INLINABLE premap #-}
-
-{-| @(premapM f folder)@ returns a new 'FoldM' where f is applied to each input
-    element
-
-> foldM (premapM f folder) list = foldM folder (map f list)
-
-> premapM id = id
->
-> premapM (f . g) = premap g . premap f
-
-> premapM k (pure r) = pure r
->
-> premapM k (f <*> x) = premapM k f <*> premapM k x
--}
-premapM :: Monad m => (a -> b) -> FoldM m b r -> FoldM m a r
-premapM f (FoldM step begin done) = FoldM step' begin done
-  where
-    step' x a = step x (f a)
-{-# INLINABLE premapM #-}
-
-type Traversal' a b = forall f . Applicative f => (b -> f b) -> a -> f a
-
-{-| @(pretraverse t folder)@ traverses each incoming element using @Traversal'@
-    @t@ and folds every target of the @Traversal'@
-
->>> fold (pretraverse traverse sum) [[1..5],[6..10]]
-55
-
->>> fold (pretraverse (traverse.traverse) sum) [[Nothing, Just 2, Just 7],[Just 13, Nothing, Just 20]]
-42
-
->>> fold (pretraverse (filtered even) sum) [1,3,5,7,21,21]
-42
-
->>> fold (pretraverse _2 mconcat) [(1,"Hello "),(2,"World"),(3,"!")]
-"Hello World!"
-
-> pretraverse id = id
->
-> pretraverse (f . g) = pretraverse f . pretraverse g
-
-> pretraverse t (pure r) = pure r
->
-> pretraverse t (f <*> x) = pretraverse t f <*> pretraverse t x
--}
-pretraverse :: Traversal' a b -> Fold b r -> Fold a r
-pretraverse k (Fold step begin done) = Fold step' begin done
-  where
-    step' = flip (appEndo . getConstant . k (Constant . Endo . flip step))
-{-# INLINABLE pretraverse #-}
-
-newtype EndoM m a = EndoM { appEndoM :: a -> m a }
-
-instance Monad m => Monoid (EndoM m a) where
-    mempty = EndoM return
-    mappend (EndoM f) (EndoM g) = EndoM (f <=< g)
-
-{-| @(pretraverseM t folder)@ traverses each incoming element using @Traversal'@
-    @t@ and folds every target of the @Traversal'@
-
-> pretraverseM id = id
->
-> pretraverseM (f . g) = pretraverseM f . pretraverseM g
-
-> pretraverseM t (pure r) = pure r
->
-> pretraverseM t (f <*> x) = pretraverseM t f <*> pretraverseM t x
--}
-pretraverseM :: Monad m => Traversal' a b -> FoldM m b r -> FoldM m a r
-pretraverseM k (FoldM step begin done) = FoldM step' begin done
-  where
-    step' = flip (appEndoM . getConstant . k (Constant . EndoM . flip step))
-{-# INLINABLE pretraverseM #-}
-
-{- $reexports
-    @Control.Monad.Primitive@ re-exports the 'PrimMonad' type class
-
-    @Data.Foldable@ re-exports the 'Foldable' type class
-
-    @Data.Vector.Generic@ re-exports the 'Vector' type class
--}
+{-| This module provides efficient and streaming left folds that you can combine
+    using 'Applicative' style.
+
+    Import this module qualified to avoid clashing with the Prelude:
+
+>>> import qualified Control.Foldl as L
+
+    Use 'fold' to apply a 'Fold' to a list:
+
+>>> L.fold L.sum [1..100]
+5050
+
+    'Fold's are 'Applicative's, so you can combine them using 'Applicative'
+    combinators:
+
+>>> import Control.Applicative
+>>> let average = (/) <$> L.sum <*> L.genericLength
+
+    These combined folds will still traverse the list only once, streaming
+    efficiently over the list in constant space without space leaks:
+
+>>> L.fold average [1..10000000]
+5000000.5
+>>> L.fold ((,) <$> L.minimum <*> L.maximum) [1..10000000]
+(Just 1,Just 10000000)
+
+-}
+
+{-# LANGUAGE ExistentialQuantification, RankNTypes, Trustworthy #-}
+
+module Control.Foldl (
+    -- * Fold Types
+      Fold(..)
+    , FoldM(..)
+
+    -- * Folding
+    , fold
+    , foldM
+    , scan
+
+    -- * Folds
+    , Control.Foldl.mconcat
+    , Control.Foldl.foldMap
+    , head
+    , last
+    , lastDef
+    , null
+    , length
+    , and
+    , or
+    , all
+    , any
+    , sum
+    , product
+    , maximum
+    , minimum
+    , elem
+    , notElem
+    , find
+    , index
+    , elemIndex
+    , findIndex
+
+    -- * Generic Folds
+    , genericLength
+    , genericIndex
+
+    -- * Container folds
+    , list
+    , revList
+    , nub
+    , eqNub
+    , set
+    , vector
+
+    -- * Utilities
+    -- $utilities
+    , purely
+    , impurely
+    , generalize
+    , simplify
+    , premap
+    , premapM
+    , pretraverse
+    , pretraverseM
+
+    -- * Re-exports
+    -- $reexports
+    , module Control.Monad.Primitive
+    , module Data.Foldable
+    , module Data.Vector.Generic
+    ) where
+
+import Control.Applicative (Applicative(pure, (<*>)),liftA2)
+import Control.Foldl.Internal (Maybe'(..), lazy, Either'(..), hush)
+import Control.Monad ((<=<))
+import Control.Monad.Primitive (PrimMonad)
+import Data.Foldable (Foldable)
+import qualified Data.Foldable as F
+import Data.Functor.Constant (Constant(Constant, getConstant))
+import Data.Functor.Identity (Identity, runIdentity)
+import Data.Monoid (Monoid(mempty, mappend), Endo(Endo, appEndo))
+import Data.Vector.Generic (Vector)
+import qualified Data.Vector.Generic as V
+import qualified Data.Vector.Generic.Mutable as M
+import qualified Data.List as List
+import qualified Data.Set as Set
+import Prelude hiding
+    ( head
+    , last
+    , null
+    , length
+    , and
+    , or
+    , all
+    , any
+    , sum
+    , product
+    , maximum
+    , minimum
+    , elem
+    , notElem
+    )
+
+{-| Efficient representation of a left fold that preserves the fold's step
+    function, initial accumulator, and extraction function
+
+    This allows the 'Applicative' instance to assemble derived folds that
+    traverse the container only once
+
+    A \''Fold' a b\' processes elements of type __a__ and results in a
+    value of type __b__.
+-}
+data Fold a b
+  -- | @Fold @ @ step @ @ initial @ @ extract@
+  = forall x. Fold (x -> a -> x) x (x -> b)
+
+data Pair a b = Pair !a !b
+
+instance Functor (Fold a) where
+    fmap f (Fold step begin done) = Fold step begin (f . done)
+    {-# INLINABLE fmap #-}
+
+instance Applicative (Fold a) where
+    pure b    = Fold (\() _ -> ()) () (\() -> b)
+    {-# INLINABLE pure #-}
+
+    (Fold stepL beginL doneL) <*> (Fold stepR beginR doneR) =
+        let step (Pair xL xR) a = Pair (stepL xL a) (stepR xR a)
+            begin = Pair beginL beginR
+            done (Pair xL xR) = doneL xL (doneR xR)
+        in  Fold step begin done
+    {-# INLINABLE (<*>) #-}
+
+instance Monoid b => Monoid (Fold a b) where
+    mempty = pure mempty
+    {-# INLINABLE mempty #-}
+
+    mappend = liftA2 mappend
+    {-# INLINABLE mappend #-}
+
+instance Num b => Num (Fold a b) where
+    fromInteger = pure . fromInteger
+    {-# INLINABLE fromInteger #-}
+
+    negate = fmap negate
+    {-# INLINABLE negate #-}
+
+    abs = fmap abs
+    {-# INLINABLE abs #-}
+
+    signum = fmap signum
+    {-# INLINABLE signum #-}
+
+    (+) = liftA2 (+)
+    {-# INLINABLE (+) #-}
+
+    (*) = liftA2 (*)
+    {-# INLINABLE (*) #-}
+
+    (-) = liftA2 (-)
+    {-# INLINABLE (-) #-}
+
+instance Fractional b => Fractional (Fold a b) where
+    fromRational = pure . fromRational
+    {-# INLINABLE fromRational #-}
+
+    recip = fmap recip
+    {-# INLINABLE recip #-}
+
+    (/) = liftA2 (/)
+    {-# INLINABLE (/) #-}
+
+instance Floating b => Floating (Fold a b) where
+    pi = pure pi
+    {-# INLINABLE pi #-}
+
+    exp = fmap exp
+    {-# INLINABLE exp #-}
+
+    sqrt = fmap sqrt
+    {-# INLINABLE sqrt #-}
+
+    log = fmap log
+    {-# INLINABLE log #-}
+
+    sin = fmap sin
+    {-# INLINABLE sin #-}
+
+    tan = fmap tan
+    {-# INLINABLE tan #-}
+
+    cos = fmap cos
+    {-# INLINABLE cos #-}
+
+    asin = fmap sin
+    {-# INLINABLE asin #-}
+
+    atan = fmap atan
+    {-# INLINABLE atan #-}
+
+    acos = fmap acos
+    {-# INLINABLE acos #-}
+
+    sinh = fmap sinh
+    {-# INLINABLE sinh #-}
+
+    tanh = fmap tanh
+    {-# INLINABLE tanh #-}
+
+    cosh = fmap cosh
+    {-# INLINABLE cosh #-}
+
+    asinh = fmap asinh
+    {-# INLINABLE asinh #-}
+
+    atanh = fmap atanh
+    {-# INLINABLE atanh #-}
+
+    acosh = fmap acosh
+    {-# INLINABLE acosh #-}
+
+    (**) = liftA2 (**)
+    {-# INLINABLE (**) #-}
+
+    logBase = liftA2 logBase
+    {-# INLINABLE logBase #-}
+
+{-| Like 'Fold', but monadic.
+
+    A \''FoldM' m a b\' processes elements of type __a__ and
+    results in a monadic value of type __m b__.
+-}
+data FoldM m a b =
+  -- | @FoldM @ @ step @ @ initial @ @ extract@
+  forall x . FoldM (x -> a -> m x) (m x) (x -> m b)
+
+instance Monad m => Functor (FoldM m a) where
+    fmap f (FoldM step start done) = FoldM step start done'
+      where
+        done' x = do
+            b <- done x
+            return $! f b
+    {-# INLINABLE fmap #-}
+
+instance Monad m => Applicative (FoldM m a) where
+    pure b = FoldM (\() _ -> return ()) (return ()) (\() -> return b)
+    {-# INLINABLE pure #-}
+
+    (FoldM stepL beginL doneL) <*> (FoldM stepR beginR doneR) =
+        let step (Pair xL xR) a = do
+                xL' <- stepL xL a
+                xR' <- stepR xR a
+                return $! Pair xL' xR'
+            begin = do
+                xL <- beginL
+                xR <- beginR
+                return $! Pair xL xR
+            done (Pair xL xR) = do
+                f <- doneL xL
+                x <- doneR xR
+                return $! f x
+        in  FoldM step begin done
+    {-# INLINABLE (<*>) #-}
+
+instance (Monoid b, Monad m) => Monoid (FoldM m a b) where
+    mempty = pure mempty
+    {-# INLINABLE mempty #-}
+
+    mappend = liftA2 mappend
+    {-# INLINABLE mappend #-}
+
+instance (Monad m, Num b) => Num (FoldM m a b) where
+    fromInteger = pure . fromInteger
+    {-# INLINABLE fromInteger #-}
+
+    negate = fmap negate
+    {-# INLINABLE negate #-}
+
+    abs = fmap abs
+    {-# INLINABLE abs #-}
+
+    signum = fmap signum
+    {-# INLINABLE signum #-}
+
+    (+) = liftA2 (+)
+    {-# INLINABLE (+) #-}
+
+    (*) = liftA2 (*)
+    {-# INLINABLE (*) #-}
+
+    (-) = liftA2 (-)
+    {-# INLINABLE (-) #-}
+
+instance (Monad m, Fractional b) => Fractional (FoldM m a b) where
+    fromRational = pure . fromRational
+    {-# INLINABLE fromRational #-}
+
+    recip = fmap recip
+    {-# INLINABLE recip #-}
+
+    (/) = liftA2 (/)
+    {-# INLINABLE (/) #-}
+
+instance (Monad m, Floating b) => Floating (FoldM m a b) where
+    pi = pure pi
+    {-# INLINABLE pi #-}
+
+    exp = fmap exp
+    {-# INLINABLE exp #-}
+
+    sqrt = fmap sqrt
+    {-# INLINABLE sqrt #-}
+
+    log = fmap log
+    {-# INLINABLE log #-}
+
+    sin = fmap sin
+    {-# INLINABLE sin #-}
+
+    tan = fmap tan
+    {-# INLINABLE tan #-}
+
+    cos = fmap cos
+    {-# INLINABLE cos #-}
+
+    asin = fmap sin
+    {-# INLINABLE asin #-}
+
+    atan = fmap atan
+    {-# INLINABLE atan #-}
+
+    acos = fmap acos
+    {-# INLINABLE acos #-}
+
+    sinh = fmap sinh
+    {-# INLINABLE sinh #-}
+
+    tanh = fmap tanh
+    {-# INLINABLE tanh #-}
+
+    cosh = fmap cosh
+    {-# INLINABLE cosh #-}
+
+    asinh = fmap asinh
+    {-# INLINABLE asinh #-}
+
+    atanh = fmap atanh
+    {-# INLINABLE atanh #-}
+
+    acosh = fmap acosh
+    {-# INLINABLE acosh #-}
+
+    (**) = liftA2 (**)
+    {-# INLINABLE (**) #-}
+
+    logBase = liftA2 logBase
+    {-# INLINABLE logBase #-}
+
+-- | Apply a strict left 'Fold' to a 'Foldable' container
+fold :: Foldable f => Fold a b -> f a -> b
+fold (Fold step begin done) as = F.foldr cons done as begin
+  where
+    cons a k x = k $! step x a
+{-# INLINE fold #-}
+
+-- | Like 'fold', but monadic
+foldM :: (Foldable f, Monad m) => FoldM m a b -> f a -> m b
+foldM (FoldM step begin done) as0 = do
+    x0 <- begin
+    F.foldr step' done as0 $! x0
+  where
+    step' a k x = do
+        x' <- step x a
+        k $! x'
+{-# INLINE foldM #-}
+
+-- | Convert a strict left 'Fold' into a scan
+scan :: Fold a b -> [a] -> [b]
+scan (Fold step begin done) as = foldr cons nil as begin
+  where
+    nil      x = done x:[]
+    cons a k x = done x:(k $! step x a)
+{-# INLINE scan #-}
+
+-- | Fold all values within a container using 'mappend' and 'mempty'
+mconcat :: Monoid a => Fold a a
+mconcat = Fold mappend mempty id
+{-# INLINABLE mconcat #-}
+
+-- | Convert a \"@foldMap@\" to a 'Fold'
+foldMap :: Monoid w => (a -> w) -> (w -> b) -> Fold a b
+foldMap to = Fold (\x a -> mappend x (to a)) mempty
+{-# INLINABLE foldMap #-}
+
+{-| Get the first element of a container or return 'Nothing' if the container is
+    empty
+-}
+head :: Fold a (Maybe a)
+head = Fold step Nothing' lazy
+  where
+    step x a = case x of
+        Nothing' -> Just' a
+        _        -> x
+{-# INLINABLE head #-}
+
+{-| Get the last element of a container or return 'Nothing' if the container is
+    empty
+-}
+last :: Fold a (Maybe a)
+last = Fold (const Just') Nothing' lazy
+{-# INLINABLE last #-}
+
+{-| Get the last element of a container or return a default value if the container
+    is empty
+-}
+lastDef :: a -> Fold a a
+lastDef a = Fold (\_ a' -> a') a id
+{-# INLINABLE lastDef #-}
+
+-- | Returns 'True' if the container is empty, 'False' otherwise
+null :: Fold a Bool
+null = Fold (\_ _ -> False) True id
+{-# INLINABLE null #-}
+
+-- | Return the length of the container
+length :: Fold a Int
+length = genericLength
+{- Technically, 'length' is just 'genericLength' specialized to 'Int's.  I keep
+   the two separate so that I can later provide an 'Int'-specialized
+   implementation of 'length' for performance reasons like "GHC.List" does
+   without breaking backwards compatibility.
+-}
+{-# INLINABLE length #-}
+
+-- | Returns 'True' if all elements are 'True', 'False' otherwise
+and :: Fold Bool Bool
+and = Fold (&&) True id
+{-# INLINABLE and #-}
+
+-- | Returns 'True' if any element is 'True', 'False' otherwise
+or :: Fold Bool Bool
+or = Fold (||) False id
+{-# INLINABLE or #-}
+
+{-| @(all predicate)@ returns 'True' if all elements satisfy the predicate,
+    'False' otherwise
+-}
+all :: (a -> Bool) -> Fold a Bool
+all predicate = Fold (\x a -> x && predicate a) True id
+{-# INLINABLE all #-}
+
+{-| @(any predicate)@ returns 'True' if any element satisfies the predicate,
+    'False' otherwise
+-}
+any :: (a -> Bool) -> Fold a Bool
+any predicate = Fold (\x a -> x || predicate a) False id
+{-# INLINABLE any #-}
+
+-- | Computes the sum of all elements
+sum :: Num a => Fold a a
+sum = Fold (+) 0 id
+{-# INLINABLE sum #-}
+
+-- | Computes the product all elements
+product :: Num a => Fold a a
+product = Fold (*) 1 id
+{-# INLINABLE product #-}
+
+-- | Computes the maximum element
+maximum :: Ord a => Fold a (Maybe a)
+maximum = Fold step Nothing' lazy
+  where
+    step x a = Just' (case x of
+        Nothing' -> a
+        Just' a' -> max a' a)
+{-# INLINABLE maximum #-}
+
+-- | Computes the minimum element
+minimum :: Ord a => Fold a (Maybe a)
+minimum = Fold step Nothing' lazy
+  where
+    step x a = Just' (case x of
+        Nothing' -> a
+        Just' a' -> min a' a)
+{-# INLINABLE minimum #-}
+
+{-| @(elem a)@ returns 'True' if the container has an element equal to @a@,
+    'False' otherwise
+-}
+elem :: Eq a => a -> Fold a Bool
+elem a = any (a ==)
+{-# INLINABLE elem #-}
+
+{-| @(notElem a)@ returns 'False' if the container has an element equal to @a@,
+    'True' otherwise
+-}
+notElem :: Eq a => a -> Fold a Bool
+notElem a = all (a /=)
+{-# INLINABLE notElem #-}
+
+{-| @(find predicate)@ returns the first element that satisfies the predicate or
+    'Nothing' if no element satisfies the predicate
+-}
+find :: (a -> Bool) -> Fold a (Maybe a)
+find predicate = Fold step Nothing' lazy
+  where
+    step x a = case x of
+        Nothing' -> if predicate a then Just' a else Nothing'
+        _        -> x
+{-# INLINABLE find #-}
+
+{-| @(index n)@ returns the @n@th element of the container, or 'Nothing' if the
+    container has an insufficient number of elements
+-}
+index :: Int -> Fold a (Maybe a)
+index = genericIndex
+{-# INLINABLE index #-}
+
+{-| @(elemIndex a)@ returns the index of the first element that equals @a@, or
+    'Nothing' if no element matches
+-}
+elemIndex :: Eq a => a -> Fold a (Maybe Int)
+elemIndex a = findIndex (a ==)
+{-# INLINABLE elemIndex #-}
+
+{-| @(findIndex predicate)@ returns the index of the first element that
+    satisfies the predicate, or 'Nothing' if no element satisfies the predicate
+-}
+findIndex :: (a -> Bool) -> Fold a (Maybe Int)
+findIndex predicate = Fold step (Left' 0) hush
+  where
+    step x a = case x of
+        Left' i ->
+            if predicate a
+            then Right' i
+            else Left' (i + 1)
+        _       -> x
+{-# INLINABLE findIndex #-}
+
+-- | Like 'length', except with a more general 'Num' return value
+genericLength :: Num b => Fold a b
+genericLength = Fold (\n _ -> n + 1) 0 id
+{-# INLINABLE genericLength #-}
+
+-- | Like 'index', except with a more general 'Integral' argument
+genericIndex :: Integral i => i -> Fold a (Maybe a)
+genericIndex i = Fold step (Left' 0) done
+  where
+    step x a = case x of
+        Left'  j -> if i == j then Right' a else Left' (j + 1)
+        _        -> x
+    done x = case x of
+        Left'  _ -> Nothing
+        Right' a -> Just a
+{-# INLINABLE genericIndex #-}
+
+-- | Fold all values into a list
+list :: Fold a [a]
+list = Fold (\x a -> x . (a:)) id ($ [])
+{-# INLINABLE list #-}
+
+-- | Fold all values into a list, in reverse order
+revList :: Fold a [a]
+revList = Fold (\x a -> a:x) [] id
+{-# INLINABLE revList #-}
+
+{-| /O(n log n)/.  Fold values into a list with duplicates removed, while
+    preserving their first occurrences
+-}
+nub :: Ord a => Fold a [a]
+nub = Fold step (Pair Set.empty id) fin
+  where
+    step (Pair s r) a = if Set.member a s
+      then Pair s r
+      else Pair (Set.insert a s) (r . (a :))
+    fin (Pair _ r) = r []
+{-# INLINABLE nub #-}
+
+{-| /O(n^2)/.  Fold values into a list with duplicates removed, while preserving
+    their first occurrences
+-}
+eqNub :: Eq a => Fold a [a]
+eqNub = Fold step (Pair [] id) fin
+  where
+    step (Pair known r) a = if List.elem a known
+      then Pair known r
+      else Pair (a : known) (r . (a :))
+    fin (Pair _ r) = r []
+{-# INLINABLE eqNub #-}
+
+-- | Fold values into a set
+set :: Ord a => Fold a (Set.Set a)
+set = Fold (flip Set.insert) Set.empty id
+{-# INLINABLE set #-}
+
+maxChunkSize :: Int
+maxChunkSize = 8 * 1024 * 1024
+
+-- | Fold all values into a vector
+vector :: (PrimMonad m, Vector v a) => FoldM m a (v a)
+vector = FoldM step begin done
+  where
+    begin = do
+        mv <- M.unsafeNew 10
+        return (Pair mv 0)
+    step (Pair mv idx) a = do
+        let len = M.length mv
+        mv' <- if idx >= len
+            then M.unsafeGrow mv (min len maxChunkSize)
+            else return mv
+        M.unsafeWrite mv' idx a
+        return (Pair mv' (idx + 1))
+    done (Pair mv idx) = do
+        v <- V.unsafeFreeze mv
+        return (V.unsafeTake idx v)
+{-# INLINABLE vector #-}
+
+{- $utilities
+    'purely' and 'impurely' allow you to write folds compatible with the @foldl@
+    library without incurring a @foldl@ dependency.  Write your fold to accept
+    three parameters corresponding to the step function, initial
+    accumulator, and extraction function and then users can upgrade your
+    function to accept a 'Fold' or 'FoldM' using the 'purely' or 'impurely'
+    combinators.
+
+    For example, the @pipes@ library implements a @foldM@ function in
+    @Pipes.Prelude@ with the following type:
+
+> foldM
+>     :: Monad m
+>     => (x -> a -> m x) -> m x -> (x -> m b) -> Producer a m () -> m b
+
+    @foldM@ is set up so that you can wrap it with 'impurely' to accept a
+    'FoldM' instead:
+
+> impurely foldM :: Monad m => FoldM m a b -> Producer a m () -> m b
+-}
+
+-- | Upgrade a fold to accept the 'Fold' type
+purely :: (forall x . (x -> a -> x) -> x -> (x -> b) -> r) -> Fold a b -> r
+purely f (Fold step begin done) = f step begin done
+{-# INLINABLE purely #-}
+
+-- | Upgrade a monadic fold to accept the 'FoldM' type
+impurely
+    :: Monad m
+    => (forall x . (x -> a -> m x) -> m x -> (x -> m b) -> r)
+    -> FoldM m a b
+    -> r
+impurely f (FoldM step begin done) = f step begin done
+{-# INLINABLE impurely #-}
+
+{-| Generalize a `Fold` to a `FoldM`
+
+> generalize (pure r) = pure r
+>
+> generalize (f <*> x) = generalize f <*> generalize x
+-}
+generalize :: Monad m => Fold a b -> FoldM m a b
+generalize (Fold step begin done) = FoldM step' begin' done'
+  where
+    step' x a = return (step x a)
+    begin'    = return  begin
+    done' x   = return (done x)
+{-# INLINABLE generalize #-}
+
+{-| Simplify a pure `FoldM` to a `Fold`
+
+> simplify (pure r) = pure r
+>
+> simplify (f <*> x) = simplify f <*> simplify x
+-}
+simplify :: FoldM Identity a b -> Fold a b
+simplify (FoldM step begin done) = Fold step' begin' done'
+  where
+    step' x a = runIdentity (step x a)
+    begin'    = runIdentity  begin
+    done' x   = runIdentity (done x)
+{-# INLINABLE simplify #-}
+
+{-| @(premap f folder)@ returns a new 'Fold' where f is applied at each step
+
+> fold (premap f folder) list = fold folder (map f list)
+
+>>> fold (premap Sum mconcat) [1..10]
+Sum {getSum = 55}
+
+>>> fold mconcat (map Sum [1..10])
+Sum {getSum = 55}
+
+> premap id = id
+>
+> premap (f . g) = premap g . premap f
+
+> premap k (pure r) = pure r
+>
+> premap k (f <*> x) = premap k f <*> premap k x
+-}
+premap :: (a -> b) -> Fold b r -> Fold a r
+premap f (Fold step begin done) = Fold step' begin done
+  where
+    step' x a = step x (f a)
+{-# INLINABLE premap #-}
+
+{-| @(premapM f folder)@ returns a new 'FoldM' where f is applied to each input
+    element
+
+> foldM (premapM f folder) list = foldM folder (map f list)
+
+> premapM id = id
+>
+> premapM (f . g) = premap g . premap f
+
+> premapM k (pure r) = pure r
+>
+> premapM k (f <*> x) = premapM k f <*> premapM k x
+-}
+premapM :: Monad m => (a -> b) -> FoldM m b r -> FoldM m a r
+premapM f (FoldM step begin done) = FoldM step' begin done
+  where
+    step' x a = step x (f a)
+{-# INLINABLE premapM #-}
+
+type Traversal' a b = forall f . Applicative f => (b -> f b) -> a -> f a
+
+{-| @(pretraverse t folder)@ traverses each incoming element using @Traversal'@
+    @t@ and folds every target of the @Traversal'@
+
+>>> fold (pretraverse traverse sum) [[1..5],[6..10]]
+55
+
+>>> fold (pretraverse (traverse.traverse) sum) [[Nothing, Just 2, Just 7],[Just 13, Nothing, Just 20]]
+42
+
+>>> fold (pretraverse (filtered even) sum) [1,3,5,7,21,21]
+42
+
+>>> fold (pretraverse _2 mconcat) [(1,"Hello "),(2,"World"),(3,"!")]
+"Hello World!"
+
+> pretraverse id = id
+>
+> pretraverse (f . g) = pretraverse f . pretraverse g
+
+> pretraverse t (pure r) = pure r
+>
+> pretraverse t (f <*> x) = pretraverse t f <*> pretraverse t x
+-}
+pretraverse :: Traversal' a b -> Fold b r -> Fold a r
+pretraverse k (Fold step begin done) = Fold step' begin done
+  where
+    step' = flip (appEndo . getConstant . k (Constant . Endo . flip step))
+{-# INLINABLE pretraverse #-}
+
+newtype EndoM m a = EndoM { appEndoM :: a -> m a }
+
+instance Monad m => Monoid (EndoM m a) where
+    mempty = EndoM return
+    mappend (EndoM f) (EndoM g) = EndoM (f <=< g)
+
+{-| @(pretraverseM t folder)@ traverses each incoming element using @Traversal'@
+    @t@ and folds every target of the @Traversal'@
+
+> pretraverseM id = id
+>
+> pretraverseM (f . g) = pretraverseM f . pretraverseM g
+
+> pretraverseM t (pure r) = pure r
+>
+> pretraverseM t (f <*> x) = pretraverseM t f <*> pretraverseM t x
+-}
+pretraverseM :: Monad m => Traversal' a b -> FoldM m b r -> FoldM m a r
+pretraverseM k (FoldM step begin done) = FoldM step' begin done
+  where
+    step' = flip (appEndoM . getConstant . k (Constant . EndoM . flip step))
+{-# INLINABLE pretraverseM #-}
+
+{- $reexports
+    @Control.Monad.Primitive@ re-exports the 'PrimMonad' type class
+
+    @Data.Foldable@ re-exports the 'Foldable' type class
+
+    @Data.Vector.Generic@ re-exports the 'Vector' type class
+-}
diff --git a/src/Control/Foldl/ByteString.hs b/src/Control/Foldl/ByteString.hs
--- a/src/Control/Foldl/ByteString.hs
+++ b/src/Control/Foldl/ByteString.hs
@@ -1,198 +1,198 @@
--- | Folds for byte streams
-
-module Control.Foldl.ByteString (
-    -- * Folding
-      fold
-
-    -- * Folds
-    , head
-    , last
-    , null
-    , length
-    , any
-    , all
-    , maximum
-    , minimum
-    , elem
-    , notElem
-    , find
-    , index
-    , elemIndex
-    , findIndex
-    , count
-
-    -- * Re-exports
-    -- $reexports
-    , module Control.Foldl
-    , module Data.ByteString
-    , module Data.Word
-    ) where
-
-import Control.Foldl (Fold)
-import Control.Foldl.Internal (Maybe'(..), lazy, strict, Either'(..), hush)
-import qualified Control.Foldl as L
-import Data.ByteString (ByteString)
-import qualified Data.ByteString as B
-import qualified Data.ByteString.Lazy.Internal as Lazy
-import qualified Data.ByteString.Unsafe as BU
-import Data.Word (Word8)
-import Prelude hiding (
-    head, last, null, length, any, all, maximum, minimum, elem, notElem )
-
--- | Appply a strict left 'Fold' to a lazy bytestring
-fold :: Fold ByteString a -> Lazy.ByteString -> a
-fold (L.Fold step begin done) as = done (Lazy.foldlChunks step begin as)
-{-# INLINABLE fold #-}
-
-{-| Get the first byte of a byte stream or return 'Nothing' if the stream is
-    empty
--}
-head :: Fold ByteString (Maybe Word8)
-head = L.Fold step Nothing' lazy
-  where
-    step mw8 bs =
-        if B.null bs
-        then mw8
-        else case mw8 of
-            Just' _  -> mw8
-            Nothing' -> Just' (BU.unsafeHead bs)
-{-# INLINABLE head #-}
-
-{-| Get the last byte of a byte stream or return 'Nothing' if the byte stream is
-    empty
--}
-last :: Fold ByteString (Maybe Word8)
-last = L.Fold step Nothing' lazy
-  where
-    step mw8 bs =
-        if B.null bs
-        then mw8
-        else Just' (B.last bs)
-        -- TODO: Use `unsafeLast` when Debian Stable Haskell Platform has it
-{-# INLINABLE last #-}
-
--- | Returns 'True' if the byte stream is empty, 'False' otherwise
-null :: Fold ByteString Bool
-null = L.Fold step True id
-  where
-    step isNull bs = isNull && B.null bs
-{-# INLINABLE null #-}
-
--- | Return the length of the byte stream in bytes
-length :: Num n => Fold ByteString n
-length = L.Fold (\n bs -> n + fromIntegral (B.length bs)) 0 id
-{-# INLINABLE length #-}
-
-{-| @(all predicate)@ returns 'True' if all bytes satisfy the predicate, 'False'
-    otherwise
--}
-all :: (Word8 -> Bool) -> Fold ByteString Bool
-all predicate = L.Fold (\b bs -> b && B.all predicate bs) True id
-{-# INLINABLE all #-}
-
-{-| @(any predicate)@ returns 'True' if any byte satisfies the predicate,
-    'False' otherwise
--}
-any :: (Word8 -> Bool) -> Fold ByteString Bool
-any predicate = L.Fold (\b bs -> b || B.any predicate bs) False id
-{-# INLINABLE any #-}
-
--- | Computes the maximum byte
-maximum :: Fold ByteString (Maybe Word8)
-maximum = L.Fold step Nothing' lazy
-  where
-    step mw8 bs =
-        if B.null bs
-        then mw8
-        else Just' (case mw8 of
-            Nothing' -> B.maximum bs
-            Just' w8 -> max w8 (B.maximum bs) )
-{-# INLINABLE maximum #-}
-
--- | Computes the minimum byte
-minimum :: Fold ByteString (Maybe Word8)
-minimum = L.Fold step Nothing' lazy
-  where
-    step mw8 bs =
-        if B.null bs
-        then mw8
-        else Just' (case mw8 of
-            Nothing' -> B.minimum bs
-            Just' w8 -> min w8 (B.minimum bs) )
-{-# INLINABLE minimum #-}
-
-{-| @(elem w8)@ returns 'True' if the byte stream has a byte equal to @w8@,
-    'False' otherwise
--}
-elem :: Word8 -> Fold ByteString Bool
-elem w8 = any (w8 ==)
-{-# INLINABLE elem #-}
-
-{-| @(notElem w8)@ returns 'False' if the byte stream has a byte equal to @w8@,
-    'True' otherwise
--}
-notElem :: Word8 -> Fold ByteString Bool
-notElem w8 = all (w8 /=)
-{-# INLINABLE notElem #-}
-
-{-| @(find predicate)@ returns the first byte that satisfies the predicate or
-    'Nothing' if no byte satisfies the predicate
--}
-find :: (Word8 -> Bool) -> Fold ByteString (Maybe Word8)
-find predicate = L.Fold step Nothing' lazy
-  where
-    step mw8 bs = case mw8 of
-        Nothing' -> strict (B.find predicate bs)
-        Just' _  -> mw8
-{-# INLINABLE find #-}
-
-{-| @(index n)@ returns the @n@th byte of the byte stream, or 'Nothing' if the
-    stream has an insufficient number of bytes
--}
-index :: Integral n => n -> Fold ByteString (Maybe Word8)
-index i = L.Fold step (Left' (fromIntegral i)) hush
-  where
-    step x bs = case x of
-        Left' remainder ->
-            let len = B.length bs
-            in  if remainder < len
-                then Right' (BU.unsafeIndex bs remainder)
-                else Left'  (remainder - len)
-        _               -> x
-{-# INLINABLE index #-}
-
-{-| @(elemIndex w8)@ returns the index of the first byte that equals @w8@, or
-    'Nothing' if no byte matches
--}
-elemIndex :: Num n => Word8 -> Fold ByteString (Maybe n)
-elemIndex w8 = findIndex (w8 ==)
-{-# INLINABLE elemIndex #-}
-
-{-| @(findIndex predicate)@ returns the index of the first byte that satisfies
-    the predicate, or 'Nothing' if no byte satisfies the predicate
--}
-findIndex :: Num n => (Word8 -> Bool) -> Fold ByteString (Maybe n)
-findIndex predicate = L.Fold step (Left' 0) hush
-  where
-    step x bs = case x of
-        Left' m -> case B.findIndex predicate bs of
-            Nothing -> Left'  (m + fromIntegral (B.length bs))
-            Just n  -> Right' (m + fromIntegral n)
-        _       -> x
-{-# INLINABLE findIndex #-}
-
--- | @count w8@ returns the number of times @w8@ appears
-count :: Num n => Word8 -> Fold ByteString n
-count w8 = L.Fold step 0 id
-  where
-    step n bs = n + fromIntegral (B.count w8 bs)
-{-# INLINABLE count #-}
-
-{- $reexports
-
-    "Control.Foldl" re-exports the 'Fold' type
-
-    @Data.ByteString@ re-exports the 'ByteString' type
-
-    @Data.Word@ re-exports the 'Word8' type
--}
+-- | Folds for byte streams
+
+module Control.Foldl.ByteString (
+    -- * Folding
+      fold
+
+    -- * Folds
+    , head
+    , last
+    , null
+    , length
+    , any
+    , all
+    , maximum
+    , minimum
+    , elem
+    , notElem
+    , find
+    , index
+    , elemIndex
+    , findIndex
+    , count
+
+    -- * Re-exports
+    -- $reexports
+    , module Control.Foldl
+    , module Data.ByteString
+    , module Data.Word
+    ) where
+
+import Control.Foldl (Fold)
+import Control.Foldl.Internal (Maybe'(..), lazy, strict, Either'(..), hush)
+import qualified Control.Foldl as L
+import Data.ByteString (ByteString)
+import qualified Data.ByteString as B
+import qualified Data.ByteString.Lazy.Internal as Lazy
+import qualified Data.ByteString.Unsafe as BU
+import Data.Word (Word8)
+import Prelude hiding (
+    head, last, null, length, any, all, maximum, minimum, elem, notElem )
+
+-- | Appply a strict left 'Fold' to a lazy bytestring
+fold :: Fold ByteString a -> Lazy.ByteString -> a
+fold (L.Fold step begin done) as = done (Lazy.foldlChunks step begin as)
+{-# INLINABLE fold #-}
+
+{-| Get the first byte of a byte stream or return 'Nothing' if the stream is
+    empty
+-}
+head :: Fold ByteString (Maybe Word8)
+head = L.Fold step Nothing' lazy
+  where
+    step mw8 bs =
+        if B.null bs
+        then mw8
+        else case mw8 of
+            Just' _  -> mw8
+            Nothing' -> Just' (BU.unsafeHead bs)
+{-# INLINABLE head #-}
+
+{-| Get the last byte of a byte stream or return 'Nothing' if the byte stream is
+    empty
+-}
+last :: Fold ByteString (Maybe Word8)
+last = L.Fold step Nothing' lazy
+  where
+    step mw8 bs =
+        if B.null bs
+        then mw8
+        else Just' (B.last bs)
+        -- TODO: Use `unsafeLast` when Debian Stable Haskell Platform has it
+{-# INLINABLE last #-}
+
+-- | Returns 'True' if the byte stream is empty, 'False' otherwise
+null :: Fold ByteString Bool
+null = L.Fold step True id
+  where
+    step isNull bs = isNull && B.null bs
+{-# INLINABLE null #-}
+
+-- | Return the length of the byte stream in bytes
+length :: Num n => Fold ByteString n
+length = L.Fold (\n bs -> n + fromIntegral (B.length bs)) 0 id
+{-# INLINABLE length #-}
+
+{-| @(all predicate)@ returns 'True' if all bytes satisfy the predicate, 'False'
+    otherwise
+-}
+all :: (Word8 -> Bool) -> Fold ByteString Bool
+all predicate = L.Fold (\b bs -> b && B.all predicate bs) True id
+{-# INLINABLE all #-}
+
+{-| @(any predicate)@ returns 'True' if any byte satisfies the predicate,
+    'False' otherwise
+-}
+any :: (Word8 -> Bool) -> Fold ByteString Bool
+any predicate = L.Fold (\b bs -> b || B.any predicate bs) False id
+{-# INLINABLE any #-}
+
+-- | Computes the maximum byte
+maximum :: Fold ByteString (Maybe Word8)
+maximum = L.Fold step Nothing' lazy
+  where
+    step mw8 bs =
+        if B.null bs
+        then mw8
+        else Just' (case mw8 of
+            Nothing' -> B.maximum bs
+            Just' w8 -> max w8 (B.maximum bs) )
+{-# INLINABLE maximum #-}
+
+-- | Computes the minimum byte
+minimum :: Fold ByteString (Maybe Word8)
+minimum = L.Fold step Nothing' lazy
+  where
+    step mw8 bs =
+        if B.null bs
+        then mw8
+        else Just' (case mw8 of
+            Nothing' -> B.minimum bs
+            Just' w8 -> min w8 (B.minimum bs) )
+{-# INLINABLE minimum #-}
+
+{-| @(elem w8)@ returns 'True' if the byte stream has a byte equal to @w8@,
+    'False' otherwise
+-}
+elem :: Word8 -> Fold ByteString Bool
+elem w8 = any (w8 ==)
+{-# INLINABLE elem #-}
+
+{-| @(notElem w8)@ returns 'False' if the byte stream has a byte equal to @w8@,
+    'True' otherwise
+-}
+notElem :: Word8 -> Fold ByteString Bool
+notElem w8 = all (w8 /=)
+{-# INLINABLE notElem #-}
+
+{-| @(find predicate)@ returns the first byte that satisfies the predicate or
+    'Nothing' if no byte satisfies the predicate
+-}
+find :: (Word8 -> Bool) -> Fold ByteString (Maybe Word8)
+find predicate = L.Fold step Nothing' lazy
+  where
+    step mw8 bs = case mw8 of
+        Nothing' -> strict (B.find predicate bs)
+        Just' _  -> mw8
+{-# INLINABLE find #-}
+
+{-| @(index n)@ returns the @n@th byte of the byte stream, or 'Nothing' if the
+    stream has an insufficient number of bytes
+-}
+index :: Integral n => n -> Fold ByteString (Maybe Word8)
+index i = L.Fold step (Left' (fromIntegral i)) hush
+  where
+    step x bs = case x of
+        Left' remainder ->
+            let len = B.length bs
+            in  if remainder < len
+                then Right' (BU.unsafeIndex bs remainder)
+                else Left'  (remainder - len)
+        _               -> x
+{-# INLINABLE index #-}
+
+{-| @(elemIndex w8)@ returns the index of the first byte that equals @w8@, or
+    'Nothing' if no byte matches
+-}
+elemIndex :: Num n => Word8 -> Fold ByteString (Maybe n)
+elemIndex w8 = findIndex (w8 ==)
+{-# INLINABLE elemIndex #-}
+
+{-| @(findIndex predicate)@ returns the index of the first byte that satisfies
+    the predicate, or 'Nothing' if no byte satisfies the predicate
+-}
+findIndex :: Num n => (Word8 -> Bool) -> Fold ByteString (Maybe n)
+findIndex predicate = L.Fold step (Left' 0) hush
+  where
+    step x bs = case x of
+        Left' m -> case B.findIndex predicate bs of
+            Nothing -> Left'  (m + fromIntegral (B.length bs))
+            Just n  -> Right' (m + fromIntegral n)
+        _       -> x
+{-# INLINABLE findIndex #-}
+
+-- | @count w8@ returns the number of times @w8@ appears
+count :: Num n => Word8 -> Fold ByteString n
+count w8 = L.Fold step 0 id
+  where
+    step n bs = n + fromIntegral (B.count w8 bs)
+{-# INLINABLE count #-}
+
+{- $reexports
+
+    "Control.Foldl" re-exports the 'Fold' type
+
+    @Data.ByteString@ re-exports the 'ByteString' type
+
+    @Data.Word@ re-exports the 'Word8' type
+-}
diff --git a/src/Control/Foldl/Internal.hs b/src/Control/Foldl/Internal.hs
--- a/src/Control/Foldl/Internal.hs
+++ b/src/Control/Foldl/Internal.hs
@@ -1,36 +1,36 @@
--- | Strict data types for use as internal accumulators that don't space leak
-
-module Control.Foldl.Internal (
-    -- * Strict maybe
-      Maybe'(..)
-    , lazy
-    , strict
-
-    -- * Strict Either
-    , Either'(..)
-    , hush
-    ) where
-
--- | A strict 'Maybe'
-data Maybe' a = Just' !a | Nothing'
-
--- | Convert 'Maybe'' to 'Maybe'
-lazy :: Maybe' a -> Maybe a
-lazy  Nothing' = Nothing
-lazy (Just' a) = Just a
-{-# INLINABLE lazy #-}
-
--- | Convert 'Maybe' to 'Maybe''
-strict :: Maybe a -> Maybe' a
-strict  Nothing  = Nothing'
-strict (Just a ) = Just' a
-{-# INLINABLE strict #-}
-
--- | A strict 'Either'
-data Either' a b = Left' !a | Right' !b
-
--- | Convert 'Either'' to 'Maybe'
-hush :: Either' a b -> Maybe b
-hush (Left'  _) = Nothing
-hush (Right' b) = Just b
-{-# INLINABLE hush #-}
+-- | Strict data types for use as internal accumulators that don't space leak
+
+module Control.Foldl.Internal (
+    -- * Strict maybe
+      Maybe'(..)
+    , lazy
+    , strict
+
+    -- * Strict Either
+    , Either'(..)
+    , hush
+    ) where
+
+-- | A strict 'Maybe'
+data Maybe' a = Just' !a | Nothing'
+
+-- | Convert 'Maybe'' to 'Maybe'
+lazy :: Maybe' a -> Maybe a
+lazy  Nothing' = Nothing
+lazy (Just' a) = Just a
+{-# INLINABLE lazy #-}
+
+-- | Convert 'Maybe' to 'Maybe''
+strict :: Maybe a -> Maybe' a
+strict  Nothing  = Nothing'
+strict (Just a ) = Just' a
+{-# INLINABLE strict #-}
+
+-- | A strict 'Either'
+data Either' a b = Left' !a | Right' !b
+
+-- | Convert 'Either'' to 'Maybe'
+hush :: Either' a b -> Maybe b
+hush (Left'  _) = Nothing
+hush (Right' b) = Just b
+{-# INLINABLE hush #-}
diff --git a/src/Control/Foldl/Text.hs b/src/Control/Foldl/Text.hs
--- a/src/Control/Foldl/Text.hs
+++ b/src/Control/Foldl/Text.hs
@@ -1,193 +1,193 @@
--- | Folds for text streams
-
-module Control.Foldl.Text (
-    -- * Folding
-      fold
-
-    -- * Folds
-    , head
-    , last
-    , null
-    , length
-    , any
-    , all
-    , maximum
-    , minimum
-    , elem
-    , notElem
-    , find
-    , index
-    , elemIndex
-    , findIndex
-    , count
-
-    -- * Re-exports
-    -- $reexports
-    , module Control.Foldl
-    , module Data.Text
-    ) where
-
-import Control.Foldl (Fold)
-import Control.Foldl.Internal (Maybe'(..), lazy, strict, Either'(..), hush)
-import qualified Control.Foldl as L
-import Data.Text (Text)
-import qualified Data.Text as T
-import qualified Data.Text.Lazy as Lazy
-import Prelude hiding (
-    head, last, null, length, any, all, maximum, minimum, elem, notElem )
-
--- | Apply a strict left 'Fold' to lazy text
-fold :: Fold Text a -> Lazy.Text -> a
-fold (L.Fold step begin done) as = done (Lazy.foldlChunks step begin as)
-{-# INLINABLE fold #-}
-
-{-| Get the first character of a text stream or return 'Nothing' if the stream
-    is empty
--}
-head :: Fold Text (Maybe Char)
-head = L.Fold step Nothing' lazy
-  where
-    step mc txt =
-        if T.null txt
-        then mc
-        else case mc of
-            Just' _  -> mc
-            Nothing' -> Just' (T.head txt)
-{-# INLINABLE head #-}
-
-{-| Get the last character of a text stream or return 'Nothing' if the text
-    stream is empty
--}
-last :: Fold Text (Maybe Char)
-last = L.Fold step Nothing' lazy
-  where
-    step mc txt =
-        if T.null txt
-        then mc
-        else Just' (T.last txt)
-        -- TODO: Use `unsafeLast` when Debian Stable Haskell Platform has it
-{-# INLINABLE last #-}
-
--- | Returns 'True' if the text stream is empty, 'False' otherwise
-null :: Fold Text Bool
-null = L.Fold step True id
-  where
-    step isNull txt = isNull && T.null txt 
-{-# INLINABLE null #-}
-
--- | Return the length of the text stream in characters
-length :: Num n => Fold Text n
-length = L.Fold (\n txt -> n + fromIntegral (T.length txt)) 0 id
-{-# INLINABLE length #-}
-
-{-| @(all predicate)@ returns 'True' if all characters satisfy the predicate,
-    'False' otherwise
--}
-all :: (Char -> Bool) -> Fold Text Bool
-all predicate = L.Fold (\b txt -> b && T.all predicate txt) True id
-{-# INLINABLE all #-}
-
-{-| @(any predicate)@ returns 'True' if any character satisfies the predicate,
-    'False' otherwise
--}
-any :: (Char -> Bool) -> Fold Text Bool
-any predicate = L.Fold (\b txt -> b || T.any predicate txt) False id
-{-# INLINABLE any #-}
-
--- | Computes the maximum character
-maximum :: Fold Text (Maybe Char)
-maximum = L.Fold step Nothing' lazy
-  where
-    step mc txt =
-        if T.null txt
-        then mc
-        else Just' (case mc of
-            Nothing' -> T.maximum txt
-            Just' c -> max c (T.maximum txt) )
-{-# INLINABLE maximum #-}
-
--- | Computes the minimum character
-minimum :: Fold Text (Maybe Char)
-minimum = L.Fold step Nothing' lazy
-  where
-    step mc txt =
-        if T.null txt
-        then mc
-        else Just' (case mc of
-            Nothing' -> T.minimum txt
-            Just' c -> min c (T.minimum txt) )
-{-# INLINABLE minimum #-}
-
-{-| @(elem c)@ returns 'True' if the text stream has a character equal to @c@,
-    'False' otherwise
--}
-elem :: Char -> Fold Text Bool
-elem c = any (c ==)
-{-# INLINABLE elem #-}
-
-{-| @(notElem c)@ returns 'False' if the text stream has a character equal to
-    @c@, 'True' otherwise
--}
-notElem :: Char -> Fold Text Bool
-notElem c = all (c /=)
-{-# INLINABLE notElem #-}
-
-{-| @(find predicate)@ returns the first character that satisfies the predicate
-    or 'Nothing' if no character satisfies the predicate
--}
-find :: (Char -> Bool) -> Fold Text (Maybe Char)
-find predicate = L.Fold step Nothing' lazy
-  where
-    step mc txt = case mc of
-        Nothing' -> strict (T.find predicate txt)
-        Just' _  -> mc
-{-# INLINABLE find #-}
-
-{-| @(index n)@ returns the @n@th character of the text stream, or 'Nothing' if
-    the stream has an insufficient number of characters
--}
-index :: Integral n => n -> Fold Text (Maybe Char)
-index i = L.Fold step (Left' (fromIntegral i)) hush
-  where
-    step x txt = case x of
-        Left' remainder ->
-            let len = T.length txt
-            in  if remainder < len
-                then Right' (T.index txt remainder)
-                else Left'  (remainder - len)
-        _               -> x
-{-# INLINABLE index #-}
-
-{-| @(elemIndex c)@ returns the index of the first character that equals @c@,
-    or 'Nothing' if no character matches
--}
-elemIndex :: Num n => Char -> Fold Text (Maybe n)
-elemIndex c = findIndex (c ==)
-{-# INLINABLE elemIndex #-}
-
-{-| @(findIndex predicate)@ returns the index of the first character that
-    satisfies the predicate, or 'Nothing' if no character satisfies the
-    predicate
--}
-findIndex :: Num n => (Char -> Bool) -> Fold Text (Maybe n)
-findIndex predicate = L.Fold step (Left' 0) hush
-  where
-    step x txt = case x of
-        Left' m -> case T.findIndex predicate txt of
-            Nothing -> Left'  (m + fromIntegral (T.length txt))
-            Just n  -> Right' (m + fromIntegral n)
-        _       -> x
-{-# INLINABLE findIndex #-}
-
--- | @(count c)@ returns the number of times @c@ appears
-count :: Num n => Char -> Fold Text n
-count c = L.Fold step 0 id
-  where
-    step n txt = n + fromIntegral (T.count (T.singleton c) txt)
-{-# INLINABLE count #-}
-
-{- $reexports
-    "Control.Foldl" re-exports the 'Fold' type
-
-    @Data.Text@ re-exports the 'Text' type
--}
+-- | Folds for text streams
+
+module Control.Foldl.Text (
+    -- * Folding
+      fold
+
+    -- * Folds
+    , head
+    , last
+    , null
+    , length
+    , any
+    , all
+    , maximum
+    , minimum
+    , elem
+    , notElem
+    , find
+    , index
+    , elemIndex
+    , findIndex
+    , count
+
+    -- * Re-exports
+    -- $reexports
+    , module Control.Foldl
+    , module Data.Text
+    ) where
+
+import Control.Foldl (Fold)
+import Control.Foldl.Internal (Maybe'(..), lazy, strict, Either'(..), hush)
+import qualified Control.Foldl as L
+import Data.Text (Text)
+import qualified Data.Text as T
+import qualified Data.Text.Lazy as Lazy
+import Prelude hiding (
+    head, last, null, length, any, all, maximum, minimum, elem, notElem )
+
+-- | Apply a strict left 'Fold' to lazy text
+fold :: Fold Text a -> Lazy.Text -> a
+fold (L.Fold step begin done) as = done (Lazy.foldlChunks step begin as)
+{-# INLINABLE fold #-}
+
+{-| Get the first character of a text stream or return 'Nothing' if the stream
+    is empty
+-}
+head :: Fold Text (Maybe Char)
+head = L.Fold step Nothing' lazy
+  where
+    step mc txt =
+        if T.null txt
+        then mc
+        else case mc of
+            Just' _  -> mc
+            Nothing' -> Just' (T.head txt)
+{-# INLINABLE head #-}
+
+{-| Get the last character of a text stream or return 'Nothing' if the text
+    stream is empty
+-}
+last :: Fold Text (Maybe Char)
+last = L.Fold step Nothing' lazy
+  where
+    step mc txt =
+        if T.null txt
+        then mc
+        else Just' (T.last txt)
+        -- TODO: Use `unsafeLast` when Debian Stable Haskell Platform has it
+{-# INLINABLE last #-}
+
+-- | Returns 'True' if the text stream is empty, 'False' otherwise
+null :: Fold Text Bool
+null = L.Fold step True id
+  where
+    step isNull txt = isNull && T.null txt 
+{-# INLINABLE null #-}
+
+-- | Return the length of the text stream in characters
+length :: Num n => Fold Text n
+length = L.Fold (\n txt -> n + fromIntegral (T.length txt)) 0 id
+{-# INLINABLE length #-}
+
+{-| @(all predicate)@ returns 'True' if all characters satisfy the predicate,
+    'False' otherwise
+-}
+all :: (Char -> Bool) -> Fold Text Bool
+all predicate = L.Fold (\b txt -> b && T.all predicate txt) True id
+{-# INLINABLE all #-}
+
+{-| @(any predicate)@ returns 'True' if any character satisfies the predicate,
+    'False' otherwise
+-}
+any :: (Char -> Bool) -> Fold Text Bool
+any predicate = L.Fold (\b txt -> b || T.any predicate txt) False id
+{-# INLINABLE any #-}
+
+-- | Computes the maximum character
+maximum :: Fold Text (Maybe Char)
+maximum = L.Fold step Nothing' lazy
+  where
+    step mc txt =
+        if T.null txt
+        then mc
+        else Just' (case mc of
+            Nothing' -> T.maximum txt
+            Just' c -> max c (T.maximum txt) )
+{-# INLINABLE maximum #-}
+
+-- | Computes the minimum character
+minimum :: Fold Text (Maybe Char)
+minimum = L.Fold step Nothing' lazy
+  where
+    step mc txt =
+        if T.null txt
+        then mc
+        else Just' (case mc of
+            Nothing' -> T.minimum txt
+            Just' c -> min c (T.minimum txt) )
+{-# INLINABLE minimum #-}
+
+{-| @(elem c)@ returns 'True' if the text stream has a character equal to @c@,
+    'False' otherwise
+-}
+elem :: Char -> Fold Text Bool
+elem c = any (c ==)
+{-# INLINABLE elem #-}
+
+{-| @(notElem c)@ returns 'False' if the text stream has a character equal to
+    @c@, 'True' otherwise
+-}
+notElem :: Char -> Fold Text Bool
+notElem c = all (c /=)
+{-# INLINABLE notElem #-}
+
+{-| @(find predicate)@ returns the first character that satisfies the predicate
+    or 'Nothing' if no character satisfies the predicate
+-}
+find :: (Char -> Bool) -> Fold Text (Maybe Char)
+find predicate = L.Fold step Nothing' lazy
+  where
+    step mc txt = case mc of
+        Nothing' -> strict (T.find predicate txt)
+        Just' _  -> mc
+{-# INLINABLE find #-}
+
+{-| @(index n)@ returns the @n@th character of the text stream, or 'Nothing' if
+    the stream has an insufficient number of characters
+-}
+index :: Integral n => n -> Fold Text (Maybe Char)
+index i = L.Fold step (Left' (fromIntegral i)) hush
+  where
+    step x txt = case x of
+        Left' remainder ->
+            let len = T.length txt
+            in  if remainder < len
+                then Right' (T.index txt remainder)
+                else Left'  (remainder - len)
+        _               -> x
+{-# INLINABLE index #-}
+
+{-| @(elemIndex c)@ returns the index of the first character that equals @c@,
+    or 'Nothing' if no character matches
+-}
+elemIndex :: Num n => Char -> Fold Text (Maybe n)
+elemIndex c = findIndex (c ==)
+{-# INLINABLE elemIndex #-}
+
+{-| @(findIndex predicate)@ returns the index of the first character that
+    satisfies the predicate, or 'Nothing' if no character satisfies the
+    predicate
+-}
+findIndex :: Num n => (Char -> Bool) -> Fold Text (Maybe n)
+findIndex predicate = L.Fold step (Left' 0) hush
+  where
+    step x txt = case x of
+        Left' m -> case T.findIndex predicate txt of
+            Nothing -> Left'  (m + fromIntegral (T.length txt))
+            Just n  -> Right' (m + fromIntegral n)
+        _       -> x
+{-# INLINABLE findIndex #-}
+
+-- | @(count c)@ returns the number of times @c@ appears
+count :: Num n => Char -> Fold Text n
+count c = L.Fold step 0 id
+  where
+    step n txt = n + fromIntegral (T.count (T.singleton c) txt)
+{-# INLINABLE count #-}
+
+{- $reexports
+    "Control.Foldl" re-exports the 'Fold' type
+
+    @Data.Text@ re-exports the 'Text' type
+-}
