diff --git a/category-printf.cabal b/category-printf.cabal
--- a/category-printf.cabal
+++ b/category-printf.cabal
@@ -1,5 +1,5 @@
 name:                category-printf
-version:             0.1.0.0
+version:             0.1.0.1
 synopsis:            Highbrow approach to type-safe printf format specifications.
 description:         We use the co-Kleisli category for the comonad of
                      functions out of a fixed monoid to implement a generic
@@ -29,6 +29,6 @@
                        Control.Category.Printf.ByteString.Lazy
   
   other-extensions:    OverloadedStrings, FlexibleInstances, TypeFamilies
-  build-depends:       base >=4.7 && <4.8, comonad >=5 && <5.1, text >=1.1 && <1.2, bytestring >=0.10 && <0.11
+  build-depends:       base ==4.*, comonad >=5 && <5.1, text >=1.1 && <1.3, bytestring >=0.10 && <0.11
   hs-source-dirs:      src
   default-language:    Haskell2010
diff --git a/src/Control/Category/Printf.hs b/src/Control/Category/Printf.hs
--- a/src/Control/Category/Printf.hs
+++ b/src/Control/Category/Printf.hs
@@ -2,6 +2,7 @@
 
 module Control.Category.Printf 
        ( module Control.Category
+       -- * Basics
        , Format
        , printfWith
        , sprintf
@@ -10,12 +11,14 @@
        , spliceWith
        , s
        , generalizeString
+       -- * Numeric formatting
        , intAtBase
        , hex
        , oct
        , eFloat
        , fFloat
        , gFloat
+       -- * Argument stack manipulation
        , push
        , dup
        , swap
@@ -34,13 +37,12 @@
 import Data.String
 
 -- | Handy type synonym for the things we're working with.
-type Format m = Cokleisli ((->) m)
-
--- | You should regard a value of type @Format m a b@ as something which explains how to write
+-- You should regard a value of type @Format m a b@ as something which explains how to write
 -- some element of the monoid @m@ (a "string" for our purposes), and which will change the type
 -- of printf from @a@ to @b@. For instance, something which adds a responsibility to provide an
 -- additional argument of type @t@ might have type @Format m a (t -> a)@, while a formatter which
 -- somehow absolves you of that responsibility would have type @Format m (t -> a) a@.
+type Format m = Cokleisli ((->) m)
 
 -- | We can apply this to something like putStrLn to get a function for formatted printing.
 -- Typically you'll have @r = IO ()@, but that needn't be the case.
@@ -56,24 +58,28 @@
 
 -- | Formatter for a constant string.
 c :: (Monoid m) => m -> Format m a a
-c x = Cokleisli (\k -> k x)
+c x = Cokleisli ($ x)
 
--- | Inclusion of a string directly.
+-- | Inclusion of a string as an argument.
 i :: Format m a (m -> a)
 i = Cokleisli id
 
 -- | Given a way to turn a value of type t into a string, this builds a
 -- formatter which demands an additional argument of type t and splices it in.
 spliceWith :: (Monoid m) => (t -> m) -> Format m a (t -> a)
-spliceWith f = Cokleisli (\k n -> k (f n))
+spliceWith f = Cokleisli (. f)
 
 -- | Splice in anything showable.
 s :: (Monoid s, IsString s, Show t) => Format s a (t -> a)
 s = spliceWith (fromString . show)
 
+-- | Transform a formatter for one type of string to another using the given function.
+mapMonoid :: (m -> m') -> Format m a b -> Format m' a b
+mapMonoid u f = Cokleisli (\k -> runCokleisli f (k . u))
+
 -- | Generalizes the string type that a formatter uses by applying fromString internally.
 generalizeString :: (IsString s, Monoid s) => Format String a b -> Format s a b
-generalizeString f = Cokleisli (\k -> runCokleisli f (k . fromString))
+generalizeString = mapMonoid fromString
 
 -- | Show an integral value using the given base, and using the provided function to determine how
 -- to display individual digits.
