diff --git a/Data/FMList.hs b/Data/FMList.hs
--- a/Data/FMList.hs
+++ b/Data/FMList.hs
@@ -11,23 +11,25 @@
 -- FoldMap lists: lists represented by their foldMap function.
 --
 -----------------------------------------------------------------------------
-{-# LANGUAGE Rank2Types #-}
+{-# LANGUAGE RankNTypes #-}
 
 module Data.FMList ( 
 
     FMList(..)
+  , transform
     
+  -- * Construction  
   , empty
   , singleton
   , cons
   , snoc
   , append
-  , flatten
   
   , toList
   , fromList
   , fromFoldable
   
+  -- * Basic functions
   , null
   , length
   , genericLength
@@ -38,6 +40,8 @@
   , init
   , reverse
   
+  -- * Folding
+  , flatten
   , filter
   , take
   , drop
@@ -47,6 +51,7 @@
   , zip
   , zipWith
   
+  -- * Unfolding
   , iterate
   , repeat
   , unfoldr
@@ -68,8 +73,48 @@
 import Control.Monad
 import Control.Applicative
 
+
+-- | FMList is a foldMap function wrapped up in a newtype.
+-- Examples:
+--
+-- > -- A right-infinite list
+-- > c = 1 `cons` c
+--
+-- > -- A left-infinite list
+-- > d = d `snoc` 2
+--
+-- > -- A middle-infinite list ??
+-- > e = c `append` d
+--
+-- > *> head e
+-- > 1
+-- > *> last e
+-- > 2
+-- 
 newtype FMList a = FM { unFM :: forall b . Monoid b => (a -> b) -> b }
 
+-- | Transform transforms a list by changing the map function that is passed to foldMap.
+-- It has the following property:
+--
+-- @transform a . transform b = transform (b . a)@
+--
+-- For example:
+--
+--  * @  m >>= g@
+--
+--  * @= flatten (fmap g m)@
+--
+--  * @= flatten . fmap g $ m@
+--
+--  * @= transform foldMap . transform (. g) $ m@
+--
+--  * @= transform ((. g) . foldMap) m@
+--
+--  * @= transform (\\f -> foldMap f . g) m@
+-- 
+transform :: (forall b. Monoid b => (a -> b) -> (c -> b)) -> FMList c -> FMList a
+transform t l = FM $ \f -> unFM l (t f)
+
 -- nil is exported as empty from Applicative
 nil          :: FMList a
 nil          = FM $ \_ -> mempty
@@ -87,11 +132,7 @@
 -- append l r  = FM $ \f -> unFM l f `mappend` unFM r f
 append l r   = FM $ unFM l `mappend` unFM r
 
-flatten      :: FMList (FMList a) -> FMList a
--- flatten l    = FM $ \f -> unFM l (foldMap f)
-flatten l    = FM $ unFM l . foldMap
 
-
 fromList     :: [a] -> FMList a
 fromList     = fromFoldable
 
@@ -125,8 +166,11 @@
 reverse l    = FM $ \f -> getDual $ unFM l (Dual . f)
 
 
+flatten      :: FMList (FMList a) -> FMList a
+flatten      = transform foldMap
+
 filter       :: (a -> Bool) -> FMList a -> FMList a
-filter p l   = FM $ \f -> unFM l $ \e -> if p e then f e else mempty
+filter p     = transform (\f e -> if p e then f e else mempty)
 
 take         :: (Ord n, Num n) => n -> FMList a -> FMList a
 take n l     = FM $ \f -> 
@@ -172,7 +216,7 @@
 
 
 instance Functor FMList where
-  fmap g c   = FM $ \f -> unFM c (f . g)
+  fmap g     = transform (. g)
   
 instance Foldable FMList where
   foldMap    = flip unFM
@@ -182,11 +226,11 @@
 
 instance Monad FMList where
   return     = singleton
-  m >>= g    = FM $ \f -> unFM m (foldMap f . g)
+  m >>= g    = transform (\f -> foldMap f . g) m
 
 instance Applicative FMList where
   pure       = return
-  gs <*> xs  = FM $ \f -> unFM gs (\g -> unFM xs (f . g))
+  gs <*> xs  = transform (\f g -> unFM xs (f . g)) gs
     
 instance Monoid (FMList a) where
   mempty     = nil
diff --git a/fmlist.cabal b/fmlist.cabal
--- a/fmlist.cabal
+++ b/fmlist.cabal
@@ -1,5 +1,5 @@
 name:                fmlist
-version:             0.3
+version:             0.4
 synopsis:            FoldMap lists
 description:         
   FoldMap lists are lists represented by their foldMap function.
