diff --git a/Numeric/AD.hs b/Numeric/AD.hs
--- a/Numeric/AD.hs
+++ b/Numeric/AD.hs
@@ -66,6 +66,10 @@
     , du'
     , duF
     , duF'
+    , dus
+    , dus0
+    , dusF
+    , dus0F
 
     -- * Taylor Series (Tower)
     , taylor
@@ -96,7 +100,7 @@
 import Numeric.AD.Classes  (Mode(..))
 import Numeric.AD.Internal (AD(..), probed, unprobe)
 import Numeric.AD.Forward  (diff, diff', diffF, diffF', du, du', duF, duF', diffM, diffM', jacobianT, jacobianWithT) 
-import Numeric.AD.Tower    (diffsF, diffs0F , diffs, diffs0, taylor, taylor0, maclaurin, maclaurin0)
+import Numeric.AD.Tower    (diffsF, diffs0F , diffs, diffs0, taylor, taylor0, maclaurin, maclaurin0, dus, dus0, dusF, dus0F)
 import Numeric.AD.Reverse  (grad, grad', gradWith, gradWith', gradM, gradM', gradWithM, gradWithM', gradF, gradF', gradWithF, gradWithF')
 import Numeric.AD.Internal.Composition
 
@@ -178,3 +182,10 @@
 -- | Compute the order 3 Hessian tensor on a non-scalar-to-non-scalar function via the forward-mode Jacobian of the mixed-mode Jacobian of the function.
 hessianTensor :: (Traversable f, Traversable g, Num a) => (forall s. Mode s => f (AD s a) -> g (AD s a)) -> f a -> g (f (f a))
 hessianTensor f = decomposeFunctor . Forward.jacobian (ComposeFunctor . jacobian (fmap decomposeMode . f . fmap composeMode))
+
+-- the cofree comonad of f
+-- data f :> a = (f :> a) :> a
+
+-- gradients :: (Traversable f, Num a) => (forall s. Mode s => f (AD s a) -> AD s a) -> f a -> (f :> a) 
+
+-- jacobians :: (Traversable f, Traversable g, Num a) => (forall s. Mode s => f (AD s a) -> g (AD s a)) -> f a -> g (f :> a) 
diff --git a/Numeric/AD/Internal/Tower.hs b/Numeric/AD/Internal/Tower.hs
--- a/Numeric/AD/Internal/Tower.hs
+++ b/Numeric/AD/Internal/Tower.hs
@@ -13,17 +13,24 @@
 module Numeric.AD.Internal.Tower
     ( Tower(..)
     , zeroPad
+    , zeroPadF
+    , transposePadF
     , d
     , d'
+    , withD
     , tangents
     , bundle
     , apply
     , getADTower
+    , tower
     ) where
 
+import Prelude hiding (all)
+import Control.Applicative
+import Data.Foldable
+import Language.Haskell.TH
 import Numeric.AD.Classes
 import Numeric.AD.Internal
-import Language.Haskell.TH
 
 -- | @Tower@ is an AD 'Mode' that calculates a tangent tower by forward AD, and provides fast 'diffsUU', 'diffsUF'
 newtype Tower a = Tower { getTower :: [a] } deriving (Show)
@@ -34,6 +41,21 @@
 zeroPad xs = xs ++ repeat 0
 {-# INLINE zeroPad #-}
 
+zeroPadF :: (Functor f, Num a) => [f a] -> [f a]
+zeroPadF fxs@(fx:_) = fxs ++ repeat (const 0 <$> fx)
+zeroPadF _ = error "zeroPadF :: empty list"
+{-# INLINE zeroPadF #-}
+
+transposePadF :: (Foldable f, Functor f) => a -> f [a] -> [f a]
+transposePadF pad fx
+    | all null fx = []
+    | otherwise = fmap headPad fx : transposePadF pad (drop1 <$> fx)
+    where
+        headPad [] = pad
+        headPad (x:_) = x
+        drop1 (_:xs) = xs
+        drop1 xs = xs
+
 d :: Num a => [a] -> a
 d (_:da:_) = da
 d _ = 0
@@ -54,6 +76,10 @@
 bundle a (Tower as) = Tower (a:as)
 {-# INLINE bundle #-}
 
+withD :: (a, a) -> AD Tower a
+withD (a, da) = AD (Tower [a,da])
+{-# INLINE withD #-}
+
 apply :: Num a => (AD Tower a -> b) -> a -> b
 apply f a = f (AD (Tower [a,1]))
 {-# INLINE apply #-}
@@ -61,6 +87,9 @@
 getADTower :: AD Tower a -> [a]
 getADTower (AD t) = getTower t
 {-# INLINE getADTower #-}
+
+tower :: [a] -> AD Tower a
+tower as = AD (Tower as)
 
 instance Primal Tower where
     primal (Tower (x:_)) = x
diff --git a/Numeric/AD/Tower.hs b/Numeric/AD/Tower.hs
--- a/Numeric/AD/Tower.hs
+++ b/Numeric/AD/Tower.hs
@@ -21,15 +21,24 @@
     , maclaurin
     , maclaurin0
     -- * Derivatives
-    , diff
-    , diff'
-    , diffs
-    , diffs0
-    , diffsF
-    , diffs0F
+    , diff    -- first derivative of (a -> a) 
+    , diff'   -- answer and first derivative of (a -> a) 
+    , diffs   -- answer and all derivatives of (a -> a) 
+    , diffs0  -- zero padded derivatives of (a -> a)
+    , diffsF  -- answer and all derivatives of (a -> f a)
+    , diffs0F -- zero padded derivatives of (a -> f a)
+    -- * Directional Derivatives
+    , du      -- directional derivative of (a -> a)
+    , du'     -- answer and directional derivative of (a -> a)
+    , dus     -- answer and all directional derivatives of (a -> a) 
+    , dus0    -- answer and all zero padded directional derivatives of (a -> a)
+    , duF     -- directional derivative of (a -> f a)
+    , duF'    -- answer and directional derivative of (a -> f a)
+    , dusF    -- answer and all directional derivatives of (a -> f a)
+    , dus0F   -- answer and all zero padded directional derivatives of (a -> a)
     -- * Monadic Combinators
-    , diffsM
-    , diffs0M
+    , diffsM  -- answer and all derivatives of the monadic action (a -> m a)
+    , diffs0M -- answer and all zero padded derivatives of (a -> m a)
     -- * Exposed Types
     , Mode(..)
     , AD(..)
@@ -84,10 +93,47 @@
 {-# INLINE maclaurin0 #-}
 
 diff :: Num a => (forall s. Mode s => AD s a -> AD s a) -> a -> a
-diff f a = d $ diffs f a
+diff f = d . diffs f
 {-# INLINE diff #-}
 
 diff' :: Num a => (forall s. Mode s => AD s a -> AD s a) -> a -> (a, a)
-diff' f a = d' $ diffs f a
+diff' f = d' . diffs f
 {-# INLINE diff' #-}
 
+du :: (Functor f, Num a) => (forall s. f (AD s a) -> AD s a) -> f (a, a) -> a
+du f = d . getADTower . f . fmap withD
+{-# INLINE du #-}
+
+du' :: (Functor f, Num a) => (forall s. f (AD s a) -> AD s a) -> f (a, a) -> (a, a)
+du' f = d' . getADTower . f . fmap withD
+{-# INLINE du' #-}
+
+duF :: (Functor f, Functor g, Num a) => (forall s. f (AD s a) -> g (AD s a)) -> f (a, a) -> g a
+duF f = fmap (d . getADTower) . f . fmap withD
+{-# INLINE duF #-}
+
+duF' :: (Functor f, Functor g, Num a) => (forall s. f (AD s a) -> g (AD s a)) -> f (a, a) -> g (a, a)
+duF' f = fmap (d' . getADTower) . f . fmap withD
+{-# INLINE duF' #-}
+
+dus :: (Functor f, Num a) => (forall s. f (AD s a) -> AD s a) -> f [a] -> [a]
+dus f = getADTower . f . fmap tower
+{-# INLINE dus #-}
+
+dus0 :: (Functor f, Num a) => (forall s. f (AD s a) -> AD s a) -> f [a] -> [a]
+dus0 f = zeroPad . getADTower . f . fmap tower
+{-# INLINE dus0 #-}
+
+dusF :: (Functor f, Functor g, Num a) => (forall s. f (AD s a) -> g (AD s a)) -> f [a] -> g [a]
+dusF f = fmap getADTower . f . fmap tower
+{-# INLINE dusF #-}
+
+dus0F :: (Functor f, Functor g, Num a) => (forall s. f (AD s a) -> g (AD s a)) -> f [a] -> g [a]
+dus0F f = fmap getADTower . f . fmap tower
+{-# INLINE dus0F #-}
+
+-- TODO: higher order gradients
+-- data f :> a = a :< f (f :> a) 
+-- gradients  :: (Traversable f, Num a) => (forall s. Mode s => f (AD s a) -> AD s a) -> f a -> f :> a
+-- gradientsF, jacobians :: (Traversable f, Functor g, Num a) => (forall s. Mode s => f (AD s a) -> g (AD s a)) -> f a -> g (f :> a)
+-- gradientsM :: (Traversable f, Monad m, Num a) => (forall s. Mode s => f (AD s a) -> m (AD s a)) -> f a -> m (f :> a)
diff --git a/ad.cabal b/ad.cabal
--- a/ad.cabal
+++ b/ad.cabal
@@ -1,5 +1,5 @@
 Name:         ad
-Version:      0.22
+Version:      0.23
 License:      BSD3
 License-File: LICENSE
 Copyright:    Edward Kmett 2010
