diff --git a/.travis.yml b/.travis.yml
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,44 +1,44 @@
-env:
- - GHCVER=7.0.1 CABALVER=1.16
- - GHCVER=7.0.4 CABALVER=1.16
- - GHCVER=7.2.2 CABALVER=1.16
- - GHCVER=7.4.2 CABALVER=1.16
- - GHCVER=7.6.3 CABALVER=1.16
- - GHCVER=7.8.4 CABALVER=1.18
- - GHCVER=7.10.1 CABALVER=1.22
- - GHCVER=head CABALVER=1.22
+language: c
+sudo: false
 
 matrix:
+  include:
+    - env: CABALVER=1.16 GHCVER=7.4.2 GHCOPTS="-Werror" JOPTS=""
+      addons: {apt: {packages: [cabal-install-1.16, ghc-7.4.2], sources: [hvr-ghc]}}
+    - env: CABALVER=1.18 GHCVER=7.6.3 GHCOPTS="-Werror" JOPTS="-j2"
+      addons: {apt: {packages: [cabal-install-1.18, ghc-7.6.3], sources: [hvr-ghc]}}
+    - env: CABALVER=1.18 GHCVER=7.8.4 GHCOPTS="-Werror" JOPTS="-j2"
+      addons: {apt: {packages: [cabal-install-1.18, ghc-7.8.4], sources: [hvr-ghc]}}
+    - env: CABALVER=1.22 GHCVER=7.10.1 GHCOPTS="" JOPTS="-j2"
+      addons: {apt: {packages: [cabal-install-1.22, ghc-7.10.1],sources: [hvr-ghc]}}
+    - env: CABALVER=head GHCVER=head GHCOPTS="" JOPTS="-j2"
+      addons: {apt: {packages: [cabal-install-head,ghc-head],  sources: [hvr-ghc]}}
+
   allow_failures:
-   - env: GHCVER=7.0.1 CABALVER=1.16
-   - env: GHCVER=7.0.4 CABALVER=1.16
-   - env: GHCVER=7.2.2 CABALVER=1.16
-   - env: GHCVER=head CABALVER=1.22
+   - env: CABALVER=head GHCVER=head GHCOPTS="" JOPTS="-j2"
 
 before_install:
- - travis_retry sudo add-apt-repository -y ppa:hvr/ghc
- - travis_retry sudo apt-get update
- - travis_retry sudo apt-get install cabal-install-$CABALVER ghc-$GHCVER
- - export PATH=/opt/ghc/$GHCVER/bin:/opt/cabal/$CABALVER/bin:$PATH
+ - export PATH=~/.cabal/bin:/opt/ghc/$GHCVER/bin:/opt/cabal/$CABALVER/bin:$PATH
  - export CABAL=cabal-$CABALVER
+ - travis_retry $CABAL update
+ - if [ "$CABALVER" = "1.22" ]; then cabal install Cabal-1.22.4.0; fi
  - $CABAL --version
+ - echo "$(ghc --version) [$(ghc --print-project-git-commit-id 2> /dev/null || echo '?')]"
 
 install:
- - travis_retry $CABAL update
- - $CABAL install "Cabal == $CABALVER.*"
- - $CABAL install --enable-tests --only-dependencies
+ - |    
+   if [ $GHCVER = "head" ] || [ $GHCVER = "7.8.4" ] || [ $GHCVER = "7.10.1" ]; then
+     $CABAL install --constraint=transformers\ installed happy alex
+     export PATH=$HOME/.cabal/bin:$PATH
+   fi
+ - $CABAL install $JOPTS --enable-tests --only-dependencies --force
 
 script:
  - $CABAL configure -v2 --enable-tests
- - $CABAL build
- - $CABAL sdist
- - export SRC_TGZ=$($CABAL info . | awk '{print $2 ".tar.gz";exit}') ;
-   cd dist/;
-   if [ -f "$SRC_TGZ" ]; then
-      $CABAL install "$SRC_TGZ";
-   else
-      echo "expected '$SRC_TGZ' not found";
-      exit 1;
+ - $CABAL build $JOPTS --ghc-options=$GHCOPTS
+ - |
+   if [ $GHCVER != "head" ]; then
+     $CABAL test
    fi
 
 notifications:
diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown
--- a/CHANGELOG.markdown
+++ b/CHANGELOG.markdown
@@ -1,3 +1,7 @@
+4.2.4
+-----
+* Added `Newton.Double` modules for performance.
+
 4.2.3
 -----
 * `reflection` 2 support
diff --git a/README.markdown b/README.markdown
--- a/README.markdown
+++ b/README.markdown
@@ -1,7 +1,7 @@
 ad
 ==
 
-[![Build Status](https://secure.travis-ci.org/ekmett/ad.png?branch=master)](http://travis-ci.org/ekmett/ad)
+[![Hackage](https://img.shields.io/hackage/v/ad.svg)](https://hackage.haskell.org/package/ad) [![Build Status](https://secure.travis-ci.org/ekmett/ad.png?branch=master)](http://travis-ci.org/ekmett/ad)
 
 A package that provides an intuitive API for [Automatic Differentiation](http://en.wikipedia.org/wiki/Automatic_differentiation) (AD) in Haskell. Automatic differentiation provides a means to calculate the derivatives of a function while evaluating it. Unlike numerical methods based on running the program with multiple inputs or symbolic approaches, automatic differentiation typically only decreases performance by a small multiplier.
 
diff --git a/TODO b/TODO
deleted file mode 100644
--- a/TODO
+++ /dev/null
@@ -1,43 +0,0 @@
-* Use the f-branching stream and tensors to generate:
-
-    gradients :: Traversable f => FU f a -> f a -> Stream f a
-
-* Allow the type to vary within our AD data type container, in the same fashion as Numeric.FAD.
-
-    Although, while Pearlmutter and Siskind provided the functionality to permit
-    it in the derivative combinators, they provided no combinators to convert,
-    say, @Dual tag Float@ to a @Dual tag Double@, so that extra functionality cannot
-    currently be leveraged.
-
-  One approach: GADT'd Tape.
-    Lets us use local matrix-valued jacobians as blackboxes.
-    However, this requires a custom higher-order data-reify.
-
-* Do we need some kind of Array implementation? These'd be easy:
-
-    (new)?type ADArray s i e = Array i (AD s e)
-    (new)?type ADIOArray s i e = IOArray i (AD s e)
-    (new)?type ADSTArray s i e = STArray i (AD s e)
-
-  But how to handle possibly unboxed arrays where possible?
-
-    Mode s => ADUArray s i Float
-    Mode s => ADIOUArray s i Float
-    Mode s => ADSTUArray s i Float
-
-  Forward admits fast unboxed array access, but how to avoid violating quantification over s?
-
-  This seems to require baking the array type for Float and Double directly into the Mode.
-
-  class ( IArray (ADArray s) e
-        , MArray (ADSTArray s s') e (ST s')
-        , MArray (ADIOArray s) e IO
-        , Lifted s) => LiftedArray s e where
-
-     type ADArr s e  :: * -> * -> *
-     type ADSTArr s e :: * -> * -> *
-     type ADIOArr s e :: * -> * -> *
-
-  newtype ADArray s i e = ADArray (ADArr s e i e)
-
-  class ( LiftedArray s Float, LiftedArray s Double, ...) => Mode s
diff --git a/ad.cabal b/ad.cabal
--- a/ad.cabal
+++ b/ad.cabal
@@ -1,5 +1,5 @@
 name:          ad
-version:       4.2.3
+version:       4.2.4
 license:       BSD3
 license-File:  LICENSE
 copyright:     (c) Edward Kmett 2010-2015,
@@ -19,7 +19,6 @@
   .gitignore
   .travis.yml
   .vim.custom
-  TODO
   CHANGELOG.markdown
   README.markdown
   travis/cabal-apt-install
@@ -77,7 +76,6 @@
   location: git://github.com/ekmett/ad.git
 
 library
-  default-extensions: CPP
   hs-source-dirs: src
   include-dirs: include
   default-language: Haskell2010
@@ -137,11 +135,13 @@
     Numeric.AD.Mode.Sparse
     Numeric.AD.Mode.Tower
     Numeric.AD.Newton
+    Numeric.AD.Newton.Double
     Numeric.AD.Rank1.Forward
     Numeric.AD.Rank1.Forward.Double
     Numeric.AD.Rank1.Halley
     Numeric.AD.Rank1.Kahn
     Numeric.AD.Rank1.Newton
+    Numeric.AD.Rank1.Newton.Double
     Numeric.AD.Rank1.Sparse
     Numeric.AD.Rank1.Tower
 
@@ -160,7 +160,7 @@
   build-depends:
     base,
     directory,
-    doctest >= 0.9.0.1 && <= 0.10,
+    doctest >= 0.9.0.1 && <= 0.11,
     filepath
   ghc-options: -Wall -threaded
   hs-source-dirs: tests
diff --git a/src/Numeric/AD.hs b/src/Numeric/AD.hs
--- a/src/Numeric/AD.hs
+++ b/src/Numeric/AD.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP #-}
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE Rank2Types #-}
 {-# LANGUAGE TypeFamilies #-}
@@ -131,7 +132,9 @@
   ) where
 
 import Data.Functor.Compose
+#if __GLASGOW_HASKELL__ < 710
 import Data.Traversable (Traversable)
+#endif
 import Data.Reflection (Reifies)
 import Numeric.AD.Internal.Forward (Forward)
 import Numeric.AD.Internal.Kahn (Grad, vgrad, vgrad')
diff --git a/src/Numeric/AD/Internal/Combinators.hs b/src/Numeric/AD/Internal/Combinators.hs
--- a/src/Numeric/AD/Internal/Combinators.hs
+++ b/src/Numeric/AD/Internal/Combinators.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP #-}
 {-# OPTIONS_GHC -fno-warn-incomplete-patterns #-}
 {-# OPTIONS_HADDOCK not-home #-}
 -----------------------------------------------------------------------------
@@ -17,8 +18,13 @@
   , fromBy
   ) where
 
+#if __GLASGOW_HASKELL__ < 710
 import Data.Traversable (Traversable, mapAccumL)
 import Data.Foldable (Foldable, toList)
+#else
+import Data.Traversable (mapAccumL)
+import Data.Foldable (toList)
+#endif
 import Numeric.AD.Mode
 import Numeric.AD.Jacobian
 
diff --git a/src/Numeric/AD/Internal/Dense.hs b/src/Numeric/AD/Internal/Dense.hs
--- a/src/Numeric/AD/Internal/Dense.hs
+++ b/src/Numeric/AD/Internal/Dense.hs
@@ -41,9 +41,16 @@
   ) where
 
 import Control.Monad (join)
+#if __GLASGOW_HASKELL__ < 710
 import Data.Functor
+#endif
 import Data.Typeable ()
-import Data.Traversable (Traversable, mapAccumL)
+import Data.Traversable
+  ( mapAccumL
+#if __GLASGOW_HASKELL__ < 710
+  , Traversable
+#endif
+  )
 import Data.Data ()
 import Data.Number.Erf
 import Numeric.AD.Internal.Combinators
diff --git a/src/Numeric/AD/Internal/Forward.hs b/src/Numeric/AD/Internal/Forward.hs
--- a/src/Numeric/AD/Internal/Forward.hs
+++ b/src/Numeric/AD/Internal/Forward.hs
@@ -36,12 +36,18 @@
   , transposeWith
   ) where
 
+
 import Control.Monad (join)
+#if __GLASGOW_HASKELL__ < 710
 import Control.Applicative hiding ((<**>))
-import Data.Data
 import Data.Foldable (Foldable, toList)
-import Data.Number.Erf
 import Data.Traversable (Traversable, mapAccumL)
+#else
+import Data.Foldable (toList)
+import Data.Traversable (mapAccumL)
+#endif
+import Data.Data
+import Data.Number.Erf
 import Numeric.AD.Internal.Combinators
 import Numeric.AD.Internal.Identity
 import Numeric.AD.Jacobian
diff --git a/src/Numeric/AD/Internal/Forward/Double.hs b/src/Numeric/AD/Internal/Forward/Double.hs
--- a/src/Numeric/AD/Internal/Forward/Double.hs
+++ b/src/Numeric/AD/Internal/Forward/Double.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP #-}
 {-# LANGUAGE BangPatterns #-}
 {-# LANGUAGE ConstraintKinds #-}
 {-# LANGUAGE FlexibleContexts #-}
@@ -33,12 +34,17 @@
   , transposeWith
   ) where
 
+#if __GLASGOW_HASKELL__ < 710
 import Control.Applicative hiding ((<**>))
-import Control.Monad (join)
 import Data.Foldable (Foldable, toList)
+import Data.Traversable (Traversable, mapAccumL)
+#else
+import Data.Foldable (toList)
+import Data.Traversable (mapAccumL)
+#endif
+import Control.Monad (join)
 import Data.Function (on)
 import Data.Number.Erf
-import Data.Traversable (Traversable, mapAccumL)
 import Numeric.AD.Internal.Combinators
 import Numeric.AD.Internal.Identity
 import Numeric.AD.Jacobian
diff --git a/src/Numeric/AD/Internal/Identity.hs b/src/Numeric/AD/Internal/Identity.hs
--- a/src/Numeric/AD/Internal/Identity.hs
+++ b/src/Numeric/AD/Internal/Identity.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP #-}
 {-# LANGUAGE DeriveDataTypeable #-}
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE FlexibleInstances #-}
@@ -24,7 +25,9 @@
   ) where
 
 import Data.Data (Data)
+#if __GLASGOW_HASKELL__ < 710
 import Data.Monoid
+#endif
 import Data.Number.Erf
 import Data.Typeable (Typeable)
 import Numeric.AD.Mode
diff --git a/src/Numeric/AD/Internal/Kahn.hs b/src/Numeric/AD/Internal/Kahn.hs
--- a/src/Numeric/AD/Internal/Kahn.hs
+++ b/src/Numeric/AD/Internal/Kahn.hs
@@ -48,8 +48,11 @@
   , varId
   ) where
 
+#if __GLASGOW_HASKELL__ < 710
 import Prelude hiding (mapM)
 import Control.Applicative (Applicative(..),(<$>))
+import Data.Traversable (Traversable, mapM)
+#endif
 import Control.Monad.ST
 import Control.Monad hiding (mapM)
 import Control.Monad.Trans.State
@@ -63,7 +66,6 @@
 import qualified Data.Reify.Graph as Reified
 import System.IO.Unsafe (unsafePerformIO)
 import Data.Data (Data)
-import Data.Traversable (Traversable, mapM)
 import Data.Typeable (Typeable)
 import Numeric.AD.Internal.Combinators
 import Numeric.AD.Internal.Identity
diff --git a/src/Numeric/AD/Internal/Or.hs b/src/Numeric/AD/Internal/Or.hs
--- a/src/Numeric/AD/Internal/Or.hs
+++ b/src/Numeric/AD/Internal/Or.hs
@@ -28,7 +28,9 @@
   , binary
   ) where
 
+#if __GLASGOW_HASKELL__ < 710
 import Control.Applicative
+#endif
 import Data.Number.Erf
 #if __GLASGOW_HASKELL__ >= 707
 import Data.Typeable
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
@@ -64,7 +64,11 @@
 import Data.Number.Erf
 import Data.Proxy
 import Data.Reflection
+#if __GLASGOW_HASKELL__ < 710
 import Data.Traversable (Traversable, mapM)
+#else
+import Data.Traversable (mapM)
+#endif
 import Data.Typeable
 import Numeric.AD.Internal.Combinators
 import Numeric.AD.Internal.Identity
diff --git a/src/Numeric/AD/Internal/Sparse.hs b/src/Numeric/AD/Internal/Sparse.hs
--- a/src/Numeric/AD/Internal/Sparse.hs
+++ b/src/Numeric/AD/Internal/Sparse.hs
@@ -42,7 +42,9 @@
   ) where
 
 import Prelude hiding (lookup)
+#if __GLASGOW_HASKELL__ < 710
 import Control.Applicative hiding ((<**>))
+#endif
 import Control.Comonad.Cofree
 import Control.Monad (join)
 import Data.Data
diff --git a/src/Numeric/AD/Internal/Tower.hs b/src/Numeric/AD/Internal/Tower.hs
--- a/src/Numeric/AD/Internal/Tower.hs
+++ b/src/Numeric/AD/Internal/Tower.hs
@@ -35,7 +35,9 @@
   ) where
 
 import Prelude hiding (all)
+#if __GLASGOW_HASKELL__ < 710
 import Control.Applicative hiding ((<**>))
+#endif
 import Control.Monad (join)
 import Data.Foldable
 import Data.Data (Data)
diff --git a/src/Numeric/AD/Jet.hs b/src/Numeric/AD/Jet.hs
--- a/src/Numeric/AD/Jet.hs
+++ b/src/Numeric/AD/Jet.hs
@@ -26,10 +26,13 @@
 #define MIN_VERSION_base(x,y,z) 1
 #endif
 
+#if __GLASGOW_HASKELL__ < 710
 import Control.Applicative
 import Data.Foldable
 import Data.Traversable
 import Data.Monoid
+#endif
+
 import Data.Typeable
 import Control.Comonad.Cofree
 
diff --git a/src/Numeric/AD/Mode/Forward.hs b/src/Numeric/AD/Mode/Forward.hs
--- a/src/Numeric/AD/Mode/Forward.hs
+++ b/src/Numeric/AD/Mode/Forward.hs
@@ -44,7 +44,9 @@
   , duF'
   ) where
 
+#if __GLASGOW_HASKELL__ < 710
 import Data.Traversable (Traversable)
+#endif
 import Numeric.AD.Internal.Forward
 import Numeric.AD.Internal.On
 import Numeric.AD.Internal.Type
diff --git a/src/Numeric/AD/Mode/Forward/Double.hs b/src/Numeric/AD/Mode/Forward/Double.hs
--- a/src/Numeric/AD/Mode/Forward/Double.hs
+++ b/src/Numeric/AD/Mode/Forward/Double.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP #-}
 {-# LANGUAGE Rank2Types #-}
 -----------------------------------------------------------------------------
 -- |
@@ -40,7 +41,9 @@
   , duF'
   ) where
 
+#if __GLASGOW_HASKELL__ < 710
 import Data.Traversable (Traversable)
+#endif
 import Numeric.AD.Internal.Type (AD(AD), runAD)
 import Numeric.AD.Internal.Forward.Double (ForwardDouble)
 import qualified Numeric.AD.Rank1.Forward.Double as Rank1
diff --git a/src/Numeric/AD/Mode/Kahn.hs b/src/Numeric/AD/Mode/Kahn.hs
--- a/src/Numeric/AD/Mode/Kahn.hs
+++ b/src/Numeric/AD/Mode/Kahn.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP #-}
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE FunctionalDependencies #-}
 {-# LANGUAGE MultiParamTypeClasses #-}
@@ -45,7 +46,9 @@
   , diffF'
   ) where
 
+#if __GLASGOW_HASKELL__ < 710
 import Data.Traversable (Traversable)
+#endif
 import Numeric.AD.Internal.Kahn (Kahn)
 import Numeric.AD.Internal.On
 import Numeric.AD.Internal.Type (AD(..))
diff --git a/src/Numeric/AD/Mode/Reverse.hs b/src/Numeric/AD/Mode/Reverse.hs
--- a/src/Numeric/AD/Mode/Reverse.hs
+++ b/src/Numeric/AD/Mode/Reverse.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP #-}
 {-# LANGUAGE Rank2Types #-}
 {-# LANGUAGE TemplateHaskell #-}
 {-# LANGUAGE BangPatterns #-}
@@ -44,10 +45,12 @@
   , diffF'
   ) where
 
-import Control.Applicative ((<$>))
+#if __GLASGOW_HASKELL__ < 710
+import Data.Functor ((<$>))
+import Data.Traversable (Traversable)
+#endif
 import Data.Functor.Compose
 import Data.Reflection (Reifies)
-import Data.Traversable (Traversable)
 import Numeric.AD.Internal.On
 import Numeric.AD.Internal.Reverse
 import Numeric.AD.Mode
diff --git a/src/Numeric/AD/Mode/Sparse.hs b/src/Numeric/AD/Mode/Sparse.hs
--- a/src/Numeric/AD/Mode/Sparse.hs
+++ b/src/Numeric/AD/Mode/Sparse.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP #-}
 {-# LANGUAGE Rank2Types #-}
 -----------------------------------------------------------------------------
 -- |
@@ -36,7 +37,9 @@
   ) where
 
 import Control.Comonad.Cofree (Cofree)
+#if __GLASGOW_HASKELL__ < 710
 import Data.Traversable (Traversable)
+#endif
 import Numeric.AD.Internal.Sparse (Sparse)
 import qualified Numeric.AD.Rank1.Sparse as Rank1
 import Numeric.AD.Internal.Type
diff --git a/src/Numeric/AD/Newton/Double.hs b/src/Numeric/AD/Newton/Double.hs
new file mode 100644
--- /dev/null
+++ b/src/Numeric/AD/Newton/Double.hs
@@ -0,0 +1,130 @@
+{-# LANGUAGE Rank2Types #-}
+{-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeFamilies #-}
+-----------------------------------------------------------------------------
+-- |
+-- Copyright   :  (c) Edward Kmett 2015
+-- License     :  BSD3
+-- Maintainer  :  ekmett@gmail.com
+-- Stability   :  experimental
+-- Portability :  GHC only
+--
+-----------------------------------------------------------------------------
+
+module Numeric.AD.Newton.Double
+  (
+  -- * Newton's Method (Forward AD)
+    findZero
+  , inverse
+  , fixedPoint
+  , extremum
+  -- * Gradient Ascent/Descent (Reverse AD)
+  , conjugateGradientDescent
+  , conjugateGradientAscent
+  ) where
+
+import Data.Foldable (all, sum)
+import Data.Traversable
+import Numeric.AD.Internal.Combinators
+import Numeric.AD.Internal.Forward (Forward)
+import Numeric.AD.Internal.Forward.Double (ForwardDouble)
+import Numeric.AD.Internal.On
+import Numeric.AD.Internal.Or
+import Numeric.AD.Internal.Type (AD(..))
+import Numeric.AD.Mode
+import Numeric.AD.Rank1.Kahn as Kahn (Kahn, grad)
+import qualified Numeric.AD.Rank1.Newton.Double as Rank1
+import Prelude hiding (all, mapM, sum)
+
+-- | The 'findZero' function finds a zero of a scalar function using
+-- Newton's method; its output is a stream of increasingly accurate
+-- results.  (Modulo the usual caveats.) If the stream becomes constant
+-- ("it converges"), no further elements are returned.
+--
+-- Examples:
+--
+-- >>> take 10 $ findZero (\x->x^2-4) 1
+-- [1.0,2.5,2.05,2.000609756097561,2.0000000929222947,2.000000000000002,2.0]
+findZero :: (forall s. AD s ForwardDouble -> AD s ForwardDouble) -> Double -> [Double]
+findZero f = Rank1.findZero (runAD.f.AD)
+{-# INLINE findZero #-}
+
+-- | The 'inverse' function inverts a scalar function using
+-- Newton's method; its output is a stream of increasingly accurate
+-- results.  (Modulo the usual caveats.) If the stream becomes
+-- constant ("it converges"), no further elements are returned.
+--
+-- Example:
+--
+-- >>> last $ take 10 $ inverse sqrt 1 (sqrt 10)
+-- 10.0
+inverse :: (forall s. AD s ForwardDouble -> AD s ForwardDouble) -> Double -> Double -> [Double]
+inverse f = Rank1.inverse (runAD.f.AD)
+{-# INLINE inverse  #-}
+
+-- | The 'fixedPoint' function find a fixedpoint of a scalar
+-- function using Newton's method; its output is a stream of
+-- increasingly accurate results.  (Modulo the usual caveats.)
+--
+-- If the stream becomes constant ("it converges"), no further
+-- elements are returned.
+--
+-- >>> last $ take 10 $ fixedPoint cos 1
+-- 0.7390851332151607
+fixedPoint :: (forall s. AD s ForwardDouble -> AD s ForwardDouble) -> Double -> [Double]
+fixedPoint f = Rank1.fixedPoint (runAD.f.AD)
+{-# INLINE fixedPoint #-}
+
+-- | The 'extremum' function finds an extremum of a scalar
+-- function using Newton's method; produces a stream of increasingly
+-- accurate results.  (Modulo the usual caveats.) If the stream
+-- becomes constant ("it converges"), no further elements are returned.
+--
+-- >>> last $ take 10 $ extremum cos 1
+-- 0.0
+extremum :: (forall s. AD s (On (Forward ForwardDouble)) -> AD s (On (Forward ForwardDouble))) -> Double -> [Double]
+extremum f = Rank1.extremum (runAD.f.AD)
+{-# INLINE extremum #-}
+
+-- | Perform a conjugate gradient descent using reverse mode automatic differentiation to compute the gradient, and using forward-on-forward mode for computing extrema.
+--
+-- >>> let sq x = x * x
+-- >>> let rosenbrock [x,y] = sq (1 - x) + 100 * sq (y - sq x)
+-- >>> rosenbrock [0,0]
+-- 1
+-- >>> rosenbrock (conjugateGradientDescent rosenbrock [0, 0] !! 5) < 0.1
+-- True
+conjugateGradientDescent
+  :: Traversable f
+  => (forall s. Chosen s => f (Or s (On (Forward ForwardDouble)) (Kahn Double)) -> Or s (On (Forward ForwardDouble)) (Kahn Double))
+  -> f Double -> [f Double]
+conjugateGradientDescent f = conjugateGradientAscent (negate . f)
+{-# INLINE conjugateGradientDescent #-}
+
+lfu :: Functor f => (f (Or F a b) -> Or F a b) -> f a -> a
+lfu f = runL . f . fmap L
+
+rfu :: Functor f => (f (Or T a b) -> Or T a b) -> f b -> b
+rfu f = runR . f . fmap R
+
+-- | Perform a conjugate gradient ascent using reverse mode automatic differentiation to compute the gradient.
+conjugateGradientAscent
+  :: Traversable f
+  => (forall s. Chosen s => f (Or s (On (Forward ForwardDouble)) (Kahn Double)) -> Or s (On (Forward ForwardDouble)) (Kahn Double))
+  -> f Double -> [f Double]
+conjugateGradientAscent f x0 = takeWhile (all (\a -> a == a)) (go x0 d0 d0 delta0)
+  where
+    dot x y = sum $ zipWithT (*) x y
+    d0 = Kahn.grad (rfu f) x0
+    delta0 = dot d0 d0
+    go xi _ri di deltai = xi : go xi1 ri1 di1 deltai1
+      where
+        ai = last $ take 20 $ Rank1.extremum (\a -> lfu f $ zipWithT (\x d -> auto x + a * auto d) xi di) 0
+        xi1 = zipWithT (\x d -> x + ai*d) xi di
+        ri1 = Kahn.grad (rfu f) xi1
+        deltai1 = dot ri1 ri1
+        bi1 = deltai1 / deltai
+        di1 = zipWithT (\r d -> r + bi1 * d) ri1 di
+{-# INLINE conjugateGradientAscent #-}
diff --git a/src/Numeric/AD/Rank1/Forward.hs b/src/Numeric/AD/Rank1/Forward.hs
--- a/src/Numeric/AD/Rank1/Forward.hs
+++ b/src/Numeric/AD/Rank1/Forward.hs
@@ -42,8 +42,10 @@
   , duF'
   ) where
 
+#if __GLASGOW_HASKELL__ < 710
 import Data.Traversable (Traversable)
 import Control.Applicative
+#endif
 import Numeric.AD.Internal.Forward
 import Numeric.AD.Internal.On
 import Numeric.AD.Mode
diff --git a/src/Numeric/AD/Rank1/Forward/Double.hs b/src/Numeric/AD/Rank1/Forward/Double.hs
--- a/src/Numeric/AD/Rank1/Forward/Double.hs
+++ b/src/Numeric/AD/Rank1/Forward/Double.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP #-}
 module Numeric.AD.Rank1.Forward.Double
   ( ForwardDouble
   -- * Gradient
@@ -25,8 +26,10 @@
   , duF'
   ) where
 
+#if __GLASGOW_HASKELL__ < 710
 import Control.Applicative
 import Data.Traversable (Traversable)
+#endif
 import Numeric.AD.Mode
 import Numeric.AD.Internal.Forward.Double
 
diff --git a/src/Numeric/AD/Rank1/Kahn.hs b/src/Numeric/AD/Rank1/Kahn.hs
--- a/src/Numeric/AD/Rank1/Kahn.hs
+++ b/src/Numeric/AD/Rank1/Kahn.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP #-}
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE FunctionalDependencies #-}
 {-# LANGUAGE MultiParamTypeClasses #-}
@@ -50,9 +51,11 @@
   , Grad
   ) where
 
+#if __GLASGOW_HASKELL__ < 710
 import Control.Applicative ((<$>))
-import Data.Functor.Compose
 import Data.Traversable (Traversable)
+#endif
+import Data.Functor.Compose
 import Numeric.AD.Internal.On
 import Numeric.AD.Internal.Kahn
 import Numeric.AD.Mode
diff --git a/src/Numeric/AD/Rank1/Newton.hs b/src/Numeric/AD/Rank1/Newton.hs
--- a/src/Numeric/AD/Rank1/Newton.hs
+++ b/src/Numeric/AD/Rank1/Newton.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP #-}
 {-# LANGUAGE BangPatterns #-}
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE ScopedTypeVariables #-}
@@ -26,7 +27,9 @@
 
 import Prelude hiding (all, mapM)
 import Data.Foldable (all)
+#if __GLASGOW_HASKELL__ < 710
 import Data.Traversable
+#endif
 import Numeric.AD.Mode
 import Numeric.AD.Rank1.Forward (Forward, diff, diff')
 import Numeric.AD.Rank1.Kahn as Kahn (Kahn, gradWith')
diff --git a/src/Numeric/AD/Rank1/Newton/Double.hs b/src/Numeric/AD/Rank1/Newton/Double.hs
new file mode 100644
--- /dev/null
+++ b/src/Numeric/AD/Rank1/Newton/Double.hs
@@ -0,0 +1,83 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeFamilies #-}
+-----------------------------------------------------------------------------
+-- |
+-- Copyright   :  (c) Edward Kmett 2015
+-- License     :  BSD3
+-- Maintainer  :  ekmett@gmail.com
+-- Stability   :  experimental
+-- Portability :  GHC only
+--
+-----------------------------------------------------------------------------
+
+module Numeric.AD.Rank1.Newton.Double
+  (
+  -- * Newton's Method (Forward)
+    findZero
+  , inverse
+  , fixedPoint
+  , extremum
+  ) where
+
+import Prelude hiding (all, mapM)
+import Numeric.AD.Mode
+import Numeric.AD.Rank1.Forward (Forward)
+import qualified Numeric.AD.Rank1.Forward as Forward
+import Numeric.AD.Rank1.Forward.Double (ForwardDouble, diff')
+import Numeric.AD.Internal.On
+
+-- | The 'findZero' function finds a zero of a scalar function using
+-- Newton's method; its output is a stream of increasingly accurate
+-- results.  (Modulo the usual caveats.) If the stream becomes constant
+-- ("it converges"), no further elements are returned.
+--
+-- Examples:
+--
+-- >>> take 10 $ findZero (\x->x^2-4) 1
+-- [1.0,2.5,2.05,2.000609756097561,2.0000000929222947,2.000000000000002,2.0]
+findZero :: (ForwardDouble -> ForwardDouble) -> Double -> [Double]
+findZero f = go where
+  go x = x : if x == xn then [] else go xn where
+    (y,y') = diff' f x
+    xn = x - y/y'
+{-# INLINE findZero #-}
+
+-- | The 'inverse' function inverts a scalar function using
+-- Newton's method; its output is a stream of increasingly accurate
+-- results.  (Modulo the usual caveats.) If the stream becomes
+-- constant ("it converges"), no further elements are returned.
+--
+-- Example:
+--
+-- >>> last $ take 10 $ inverse sqrt 1 (sqrt 10)
+-- 10.0
+inverse :: (ForwardDouble -> ForwardDouble) -> Double -> Double -> [Double]
+inverse f x0 y = findZero (\x -> f x - auto y) x0
+{-# INLINE inverse  #-}
+
+-- | The 'fixedPoint' function find a fixedpoint of a scalar
+-- function using Newton's method; its output is a stream of
+-- increasingly accurate results.  (Modulo the usual caveats.)
+--
+-- If the stream becomes constant ("it converges"), no further
+-- elements are returned.
+--
+-- >>> last $ take 10 $ fixedPoint cos 1
+-- 0.7390851332151607
+fixedPoint :: (ForwardDouble -> ForwardDouble) -> Double -> [Double]
+fixedPoint f = findZero (\x -> f x - x)
+{-# INLINE fixedPoint #-}
+
+-- | The 'extremum' function finds an extremum of a scalar
+-- function using Newton's method; produces a stream of increasingly
+-- accurate results.  (Modulo the usual caveats.) If the stream
+-- becomes constant ("it converges"), no further elements are returned.
+--
+-- >>> last $ take 10 $ extremum cos 1
+-- 0.0
+extremum :: (On (Forward ForwardDouble) -> On (Forward ForwardDouble)) -> Double -> [Double]
+extremum f = findZero (Forward.diff (off . f . On))
+{-# INLINE extremum #-}
diff --git a/src/Numeric/AD/Rank1/Sparse.hs b/src/Numeric/AD/Rank1/Sparse.hs
--- a/src/Numeric/AD/Rank1/Sparse.hs
+++ b/src/Numeric/AD/Rank1/Sparse.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP #-}
 -----------------------------------------------------------------------------
 -- |
 -- Copyright   : (c) Edward Kmett 2010-2015
@@ -45,7 +46,9 @@
   ) where
 
 import Control.Comonad
+#if __GLASGOW_HASKELL__ < 710
 import Data.Traversable
+#endif
 import Control.Comonad.Cofree
 import Numeric.AD.Jet
 import Numeric.AD.Internal.Sparse
diff --git a/src/Numeric/AD/Rank1/Tower.hs b/src/Numeric/AD/Rank1/Tower.hs
--- a/src/Numeric/AD/Rank1/Tower.hs
+++ b/src/Numeric/AD/Rank1/Tower.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP #-}
 {-# LANGUAGE Rank2Types #-}
 {-# LANGUAGE BangPatterns #-}
 -----------------------------------------------------------------------------
@@ -39,7 +40,9 @@
   , dus0F   -- answer and all zero padded directional derivatives of (f a -> g a)
   ) where
 
-import Control.Applicative ((<$>))
+#if __GLASGOW_HASKELL__ < 710
+import Data.Functor ((<$>))
+#endif
 import Numeric.AD.Internal.Tower
 import Numeric.AD.Mode
 
diff --git a/tests/doctests.hs b/tests/doctests.hs
--- a/tests/doctests.hs
+++ b/tests/doctests.hs
@@ -1,7 +1,10 @@
+{-# LANGUAGE CPP #-}
 module Main where
 
 import Build_doctests (deps)
+#if __GLASGOW_HASKELL__ < 710
 import Control.Applicative
+#endif
 import Control.Monad
 import Data.List
 import System.Directory
