diff --git a/Control/Monad/Constrictor.hs b/Control/Monad/Constrictor.hs
--- a/Control/Monad/Constrictor.hs
+++ b/Control/Monad/Constrictor.hs
@@ -6,32 +6,45 @@
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
 {-# LANGUAGE ScopedTypeVariables        #-}
 
+{-|
+This library provides strict versions of many
+functions in base, as well as a few functions
+that do not have lazy versions that exist in
+base (see the section on Folds).
+-}
+
 module Control.Monad.Constrictor
   ( 
-  -- * strict monadic functions 
+    -- * Strict monadic functions 
     (<$!>)
   , fmap'
   , liftM'
   , liftM2'
+  , liftM3'
+  , liftM4'
+  , liftM5'
+  , ap' 
   , mapM'
- 
-  -- * strict applicative functions
+    
+    -- * Strict applicative functions
   , traverse'
-  
-  -- * a wrapped applicative functor
-  , Ap(..)
-  
-  -- * strict monadic folds
+
+    -- * Folds
+    -- ** Stict monadic folds
   , foldlMapM'
   , foldrMapM'
-  
-  -- * non-strict applicative folds for completeness 
+    -- ** Lazy applicative folds
   , foldlMapA
   , foldrMapA
+    -- * Types
+    -- ** Wrapped applicative functor
+  , Ap(..)
   ) where
 
 import Control.Applicative
-import Control.Monad ((<$!>))
+import Control.Monad (MonadPlus)
+import Control.Monad.Fail (MonadFail)
+import Control.Monad.Fix  (MonadFix)
 import Control.Monad.Trans.Cont (evalCont, cont)
 import Data.Foldable
 import Data.Functor.Compose (Compose(..))
@@ -40,10 +53,14 @@
 import Data.Traversable (traverse)
 import GHC.Generics (Generic,Generic1)
 
--- A wrapped Applicative Functor.
+-- | A wrapped applicative functor.
 newtype Ap f a = Ap { getAp :: f a }
-  deriving (Applicative,Eq,Foldable,Functor,Generic,Generic1
-           ,Monad,Ord,Read,Show,Traversable)
+  deriving ( Alternative, Applicative
+           , Enum, Eq, Foldable, Functor
+           , Generic, Generic1
+           , Monad, MonadFail, MonadFix, MonadPlus
+           , Num, Ord, Read, Show, Traversable
+           )
 
 instance (Applicative f, Semigroup a) => Semigroup (Ap f a) where
   (Ap x) <> (Ap y) = Ap $ liftA2 (<>) x y
@@ -92,36 +109,83 @@
     bl <- f x
     k $! (mappend bl br) 
 
--- | Strict version of 'Data.Functor.fmap'.
---
--- Note this is equivalent to 'Control.Monad.<$!>',
+infixl 4 <$!>, `fmap'`, `liftM4'`
+
+-- | Strict version of 'Data.Functor.<$>'
+(<$!>) :: Monad m => (a -> b) -> m a -> m b
+{-# INLINE (<$!>) #-}
+f <$!> m = do
+  x <- m
+  pure $! f x
+
+-- Note this is equivalent to '<$!>',
 -- and is provided for convenience.
 fmap' :: Monad m => (a -> b) -> m a -> m b
+{-# INLINE fmap' #-}
 fmap' = (<$!>)
 
 -- | Strict version of 'Control.Monad.liftM'.
 --
--- Note this is equivalent to 'Control.Monad.<$!>',
+-- Note this is equivalent to '<$!>',
 -- and is provided for convenience.
 liftM' :: Monad m => (a -> b) -> m a -> m b
+{-# INLINE liftM' #-} 
 liftM' = (<$!>)
 
 -- | Strict version of 'Control.Monad.liftM2'.
---
 liftM2' :: Monad m => (a -> b -> c) -> m a -> m b -> m c
+{-# INLINE liftM2' #-}
 liftM2' f a b = do
   x <- a
   y <- b
   pure $! f x y
 
+-- | Strict version of 'Control.Monad.liftM3'.
+liftM3' :: Monad m => (a -> b -> c -> d) -> m a -> m b -> m c -> m d
+{-# INLINE liftM3' #-}
+liftM3' f a b c = do
+  x <- a
+  y <- b
+  z <- c
+  pure $! f x y z
+
+-- | Strict version of 'Control.Monad.liftM4'.
+liftM4' :: Monad m => (a -> b -> c -> d -> e) -> m a -> m b -> m c -> m d -> m e 
+{-# INLINE liftM4' #-}
+liftM4' f a b c d = do
+  x <- a
+  y <- b
+  z <- c
+  u <- d
+  pure $! f x y z u
+
+-- | Strict version of 'Control.Monad.liftM5'.
+liftM5' :: Monad m => (a -> b -> c -> d -> e -> f) -> m a -> m b -> m c -> m d -> m e -> m f
+{-# INLINE liftM5' #-}
+liftM5' f a b c d e = do
+  x <- a
+  y <- b
+  z <- c
+  u <- d
+  v <- e
+  pure $! f x y z u v
+
+-- | Strict version of 'Control.Monad.ap'
+ap' :: Monad m => m (a -> b) -> m a -> m b
+{-# INLINE ap' #-}
+ap' m1 m2 = do
+  f <- m1
+  x <- m2
+  pure $! f x
+
 -- | Strict version of 'Data.Traversable.traverse'.
---
--- Note the increased constraint from 'Functor' to 'Applicative'.
 traverse' :: (Traversable t, Applicative f) => (a -> f b) -> t a -> f (t b)
+{-# INLINE traverse' #-}
 traverse' f = fmap evalCont . getCompose . traverse (Compose . fmap (\a -> cont $ \k -> k $! a) . f)
 
 -- | Strict version of 'Control.Monad.mapM'.
 --
 -- This is just 'traverse'' specialised to 'Monad'.
 mapM' :: (Traversable t, Monad m) => (a -> m b) -> t a-> m (t b)
+{-# INLINE mapM' #-}
 mapM' = traverse'
diff --git a/constrictor.cabal b/constrictor.cabal
--- a/constrictor.cabal
+++ b/constrictor.cabal
@@ -1,9 +1,9 @@
 name:                constrictor
-version:             0.1.0.1
+version:             0.1.0.2
 synopsis:            strict versions of many things in base
-description:         strict versions of many functions in base,
-                     including some functions not present, such
-                     as foldlMapA/M, foldrMapA/M.
+description:         This package provides strict versions of many functions in
+                     base, including some functions not present, such as
+                     'foldlMapA', 'foldlMapM', 'foldrMapA', and foldrMapM.
 homepage:            https://github.com/chessai/constrictor.git
 license:             MIT
 license-file:        LICENSE
