diff --git a/foldl.cabal b/foldl.cabal
--- a/foldl.cabal
+++ b/foldl.cabal
@@ -1,5 +1,5 @@
 Name: foldl
-Version: 1.0.2
+Version: 1.0.3
 Cabal-Version: >=1.8.0.2
 Build-Type: Simple
 License: BSD3
@@ -21,11 +21,12 @@
 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.1 ,
-        vector     >= 0.7      && < 0.11
+        base         >= 4        && < 5   ,
+        bytestring   >= 0.9.2.1  && < 0.11,
+        primitive                   < 0.6 ,
+        text         >= 0.11.2.0 && < 1.2 ,
+        transformers >= 0.2.0.0  && < 0.4 ,
+        vector       >= 0.7      && < 0.11
     Exposed-Modules:
         Control.Foldl,
         Control.Foldl.ByteString,
diff --git a/src/Control/Foldl.hs b/src/Control/Foldl.hs
--- a/src/Control/Foldl.hs
+++ b/src/Control/Foldl.hs
@@ -36,6 +36,7 @@
     -- * Folding
     , fold
     , foldM
+    , scan
 
     -- * Folds
     , mconcat
@@ -71,7 +72,10 @@
     -- $utilities
     , purely
     , impurely
+    , generalize
+    , simplify
     , premap
+    , premapM
 
     -- * Re-exports
     -- $reexports
@@ -85,6 +89,7 @@
 import Control.Monad.Primitive (PrimMonad)
 import Data.Foldable (Foldable)
 import qualified Data.Foldable as F
+import Data.Functor.Identity (Identity, runIdentity)
 import Data.Monoid (Monoid(mempty, mappend))
 import Data.Vector.Generic (Vector)
 import qualified Data.Vector.Generic as V
@@ -139,7 +144,7 @@
 -- | Like 'Fold', but monadic
 data FoldM m a b = forall x . FoldM (x -> a -> m x) (m x) (x -> m b)
 
-instance (Monad m) => Functor (FoldM m a) where
+instance Monad m => Functor (FoldM m a) where
     fmap f (FoldM step start done) = FoldM step start done'
       where
         done' x = do
@@ -147,7 +152,7 @@
             return $! f b
     {-# INLINABLE fmap #-}
 
-instance (Monad m) => Applicative (FoldM m a) where
+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) =
@@ -173,10 +178,10 @@
     {-# INLINABLE mappend #-}
 
 -- | 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 step' done as begin
+fold :: Foldable f => Fold a b -> f a -> b
+fold (Fold step begin done) as = F.foldr cons done as begin
   where
-    step' x k z = k $! step z x
+    cons a k x = k $! step x a
 {-# INLINE fold #-}
 
 -- | Like 'fold', but monadic
@@ -190,13 +195,21 @@
         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 :: 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 :: Monoid w => (a -> w) -> (w -> b) -> Fold a b
 foldMap to from = Fold (\x a -> mappend x (to a)) mempty from
 {-# INLINABLE foldMap #-}
 
@@ -258,17 +271,17 @@
 {-# INLINABLE any #-}
 
 -- | Computes the sum of all elements
-sum :: (Num a) => Fold a a
+sum :: Num a => Fold a a
 sum = Fold (+) 0 id
 {-# INLINABLE sum #-}
 
 -- | Computes the product all elements
-product :: (Num a) => Fold a a
+product :: Num a => Fold a a
 product = Fold (*) 1 id
 {-# INLINABLE product #-}
 
 -- | Computes the maximum element
-maximum :: (Ord a) => Fold a (Maybe a)
+maximum :: Ord a => Fold a (Maybe a)
 maximum = Fold step Nothing' lazy
   where
     step x a = Just' (case x of
@@ -277,7 +290,7 @@
 {-# INLINABLE maximum #-}
 
 -- | Computes the minimum element
-minimum :: (Ord a) => Fold a (Maybe a)
+minimum :: Ord a => Fold a (Maybe a)
 minimum = Fold step Nothing' lazy
   where
     step x a = Just' (case x of
@@ -288,14 +301,14 @@
 {-| @(elem a)@ returns 'True' if the container has an element equal to @a@,
     'False' otherwise
 -}
-elem :: (Eq a) => a -> Fold a Bool
+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 :: Eq a => a -> Fold a Bool
 notElem a = all (a /=)
 {-# INLINABLE notElem #-}
 
@@ -320,7 +333,7 @@
 {-| @(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 :: Eq a => a -> Fold a (Maybe Int)
 elemIndex a = findIndex (a ==)
 {-# INLINABLE elemIndex #-}
 
@@ -339,12 +352,12 @@
 {-# INLINABLE findIndex #-}
 
 -- | Like 'length', except with a more general 'Num' return value
-genericLength :: (Num b) => Fold a b
+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 :: Integral i => i -> Fold a (Maybe a)
 genericIndex i = Fold step (Left' 0) done
   where
     step x a = case x of
@@ -394,13 +407,13 @@
     @Pipes.Prelude@ with the following type:
 
 > foldM
->     :: (Monad m)
+>     :: 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
+> impurely foldM :: Monad m => FoldM m a b -> Producer a m () -> m b
 -}
 
 -- | Upgrade a fold to accept the 'Fold' type
@@ -410,21 +423,51 @@
 
 -- | Upgrade a monadic fold to accept the 'FoldM' type
 impurely
-    :: (Monad m)
+    :: 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 :: 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 :: 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 f folder) list = fold folder (map f list)
 -}
 premap :: (a -> b) -> Fold b r -> Fold a r
 premap f (Fold step begin done) = Fold step' begin done
   where
-    step' x = step x . f
+    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 :: 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 #-}
 
 {- $reexports
     @Control.Monad.Primitive@ re-exports the 'PrimMonad' type class
