diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown
--- a/CHANGELOG.markdown
+++ b/CHANGELOG.markdown
@@ -1,3 +1,7 @@
+3.1.3
+-----
+* Added `conjugateGradientDescent` and `conjugateGradientAscent` to `Numeric.AD.Newton`.
+
 3.1.2
 -----
 * Dependency bump
diff --git a/Setup.hs b/Setup.hs
deleted file mode 100644
--- a/Setup.hs
+++ /dev/null
@@ -1,2 +0,0 @@
-import Distribution.Simple
-main = defaultMain
diff --git a/Setup.lhs b/Setup.lhs
new file mode 100644
--- /dev/null
+++ b/Setup.lhs
@@ -0,0 +1,7 @@
+#!/usr/bin/runhaskell
+> module Main (main) where
+
+> import Distribution.Simple
+
+> main :: IO ()
+> main = defaultMain
diff --git a/ad.cabal b/ad.cabal
--- a/ad.cabal
+++ b/ad.cabal
@@ -1,5 +1,5 @@
 name:         ad
-version:      3.1.2
+version:      3.1.3
 license:      BSD3
 license-File: LICENSE
 copyright:    (c) Edward Kmett 2010-2012,
@@ -92,6 +92,7 @@
     containers       >= 0.2 && < 0.6,
     data-reify       >= 0.6 && < 0.7,
     free             >= 3.0 && <= 3.3,
+    mtl,
     reflection       >= 1.1.6 && < 1.2,
     tagged           >= 0.4.2.1 && < 0.5,
     template-haskell >= 2.5 && < 2.9
@@ -140,6 +141,7 @@
     base == 4.*,
     directory >= 1.0 && < 1.2,
     doctest >= 0.8 && <= 0.9,
-    filepath >= 1.3 && < 1.4
+    filepath >= 1.3 && < 1.4,
+    mtl
   ghc-options: -Wall -Werror -threaded
   hs-source-dirs: tests
diff --git a/src/Numeric/AD/Internal/Composition.hs b/src/Numeric/AD/Internal/Composition.hs
--- a/src/Numeric/AD/Internal/Composition.hs
+++ b/src/Numeric/AD/Internal/Composition.hs
@@ -173,7 +173,7 @@
 
 instance (Typeable1 f, Typeable1 g, Typeable a) => Typeable (ComposeMode f g a) where
     typeOf = typeOfDefault
-    
+
 composeModeTyCon :: TyCon
 #if MIN_VERSION_base(4,4,0)
 composeModeTyCon = mkTyCon3 "ad" "Numeric.AD.Internal.Composition" "ComposeMode"
diff --git a/src/Numeric/AD/Internal/Reverse.hs b/src/Numeric/AD/Internal/Reverse.hs
--- a/src/Numeric/AD/Internal/Reverse.hs
+++ b/src/Numeric/AD/Internal/Reverse.hs
@@ -78,7 +78,7 @@
     isKnownZero _    = False
 
     isKnownConstant (Reverse Zero) = True
-    isKnownConstant (Reverse (Lift a)) = True
+    isKnownConstant (Reverse (Lift _)) = True
     isKnownConstant _ = False
 
     lift a = Reverse (Lift a)
diff --git a/src/Numeric/AD/Newton.hs b/src/Numeric/AD/Newton.hs
--- a/src/Numeric/AD/Newton.hs
+++ b/src/Numeric/AD/Newton.hs
@@ -20,14 +20,18 @@
     -- * Gradient Ascent/Descent (Reverse AD)
     , gradientDescent
     , gradientAscent
+    , conjugateGradientDescent
+    , conjugateGradientAscent
     ) where
 
-import Prelude hiding (all)
-import Data.Foldable (all)
-import Data.Traversable (Traversable)
+import Prelude hiding (all, mapM, sum)
+import Data.Functor
+import Data.Foldable (all, sum)
+import Data.Traversable
 import Numeric.AD.Types
 import Numeric.AD.Mode.Forward (diff, diff')
-import Numeric.AD.Mode.Reverse (gradWith')
+import Numeric.AD.Mode.Reverse (grad, gradWith')
+import Numeric.AD.Internal.Combinators
 import Numeric.AD.Internal.Composition
 
 -- | The 'findZero' function finds a zero of a scalar function using
@@ -109,3 +113,24 @@
 gradientAscent :: (Traversable f, Fractional a, Ord a) => (forall s. Mode s => f (AD s a) -> AD s a) -> f a -> [f a]
 gradientAscent f = gradientDescent (negate . f)
 {-# INLINE gradientAscent #-}
+
+
+conjugateGradientDescent :: (Traversable f, Fractional a, Ord a) =>
+                (forall s. Mode s => f (AD s a) -> AD s a) -> f a -> [f a]
+conjugateGradientDescent f x0 = go x0 d0 d0
+  where
+    dot x y = sum $ zipWithT (*) x y
+    d0 = negate <$> grad f x0
+    go xi ri di = xi : go xi1 ri1 di1
+      where
+        ai  = last $ take 20 $ extremum (\a -> f $ zipWithT (\x d -> lift x + a * lift d) xi di) 0
+        xi1 = zipWithT (\x d -> x + ai*d) xi di
+        ri1 = negate <$> grad f xi1
+        bi1 = max 0 $ dot ri1 (zipWithT (-) ri1 ri) / dot ri1 ri1
+        -- bi1 = max 0 $ sum (zipWithT (\a b -> a * (a - b)) ri1 ri) / dot ri1 ri1
+        di1 = zipWithT (\r d -> r * bi1*d) ri1 di
+{-# INLINE conjugateGradientDescent #-}
+
+conjugateGradientAscent :: (Traversable f, Fractional a, Ord a) => (forall s. Mode s => f (AD s a) -> AD s a) -> f a -> [f a]
+conjugateGradientAscent f = conjugateGradientDescent (negate . f)
+{-# INLINE conjugateGradientAscent #-}
