diff --git a/.travis.yml b/.travis.yml
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,1 +1,53 @@
-language: haskell
+# NB: don't set `language: haskell` here
+
+# The following enables several GHC versions to be tested; often it's enough to test only against the last release in a major GHC version. Feel free to omit lines listings versions you don't need/want testing for.
+env:
+# - CABALVER=1.16 GHCVER=6.12.3
+# - CABALVER=1.16 GHCVER=7.0.1
+# - CABALVER=1.16 GHCVER=7.0.2
+# - CABALVER=1.16 GHCVER=7.0.3
+# - CABALVER=1.16 GHCVER=7.0.4
+# - CABALVER=1.16 GHCVER=7.2.1
+# - CABALVER=1.16 GHCVER=7.2.2
+# - CABALVER=1.16 GHCVER=7.4.1
+ - CABALVER=1.16 GHCVER=7.4.2
+# - CABALVER=1.16 GHCVER=7.6.1
+# - CABALVER=1.16 GHCVER=7.6.2
+ - CABALVER=1.18 GHCVER=7.6.3
+# - CABALVER=1.18 GHCVER=7.8.1  # see note about Alex/Happy for GHC >= 7.8
+# - CABALVER=1.18 GHCVER=7.8.2
+ - CABALVER=1.18 GHCVER=7.8.3
+ - CABALVER=1.22 GHCVER=7.10.1
+# - CABALVER=head GHCVER=head   # see section about GHC HEAD snapshots
+
+# Note: the distinction between `before_install` and `install` is not important.
+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 # see note about happy/alex
+ - export PATH=/opt/ghc/$GHCVER/bin:/opt/cabal/$CABALVER/bin:$PATH
+
+install:
+ - cabal --version
+ - echo "$(ghc --version) [$(ghc --print-project-git-commit-id 2> /dev/null || echo '?')]"
+ - travis_retry cabal update
+ - cabal install --only-dependencies --enable-tests --enable-benchmarks
+
+# Here starts the actual work to be performed for the package under test; any command which exits with a non-zero exit code causes the build to fail.
+script:
+ - if [ -f configure.ac ]; then autoreconf -i; fi
+ - cabal configure --enable-tests --enable-benchmarks -v2  # -v2 provides useful information for debugging
+ - cabal build   # this builds all libraries and executables (including tests/benchmarks)
+ - cabal test
+ - cabal check
+ - cabal sdist   # tests that a source-distribution can be generated
+
+# The following scriptlet checks that the resulting source distribution can be built & installed
+ - export SRC_TGZ=$(cabal info . | awk '{print $2 ".tar.gz";exit}') ;
+   cd dist/;
+   if [ -f "$SRC_TGZ" ]; then
+      cabal install --force-reinstalls "$SRC_TGZ";
+   else
+      echo "expected '$SRC_TGZ' not found";
+      exit 1;
+   fi
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,4 +1,6 @@
 nonlinear-optimization-ad
 =========================
 
+[![Build Status](https://secure.travis-ci.org/msakai/nonlinear-optimization-ad.png?branch=master)](http://travis-ci.org/msakai/nonlinear-optimization-ad) [![Hackage](https://budueba.com/hackage/nonlinear-optimization-ad)](https://hackage.haskell.org/package/nonlinear-optimization-ad)
+
 Wrapper of nonlinear-optimization package for using with AD package.
diff --git a/nonlinear-optimization-ad.cabal b/nonlinear-optimization-ad.cabal
--- a/nonlinear-optimization-ad.cabal
+++ b/nonlinear-optimization-ad.cabal
@@ -2,7 +2,7 @@
 -- further documentation, see http://haskell.org/cabal/users-guide/
 
 name:                nonlinear-optimization-ad
-version:             0.1.0
+version:             0.2.0
 synopsis:            Wrapper of nonlinear-optimization package for using with AD package
 description:         Wrapper of nonlinear-optimization package for using with AD package
 homepage:            https://github.com/msakai/nonlinear-optimization-ad
@@ -30,10 +30,15 @@
   build-depends:
       base >=4 && <5
     , nonlinear-optimization >=0.3.7 && <0.4
-    , ad >=3.4 && <4.0
+    , ad >=3.4 && <4.3
     , vector >= 0.5 && < 0.11
+    , primitive
+    , reflection
   hs-source-dirs:      src
   default-language: Haskell2010
   other-extensions:
     ScopedTypeVariables
     Rank2Types
+    TypeFamilies
+    CPP
+
diff --git a/samples/LinearRegression.hs b/samples/LinearRegression.hs
--- a/samples/LinearRegression.hs
+++ b/samples/LinearRegression.hs
@@ -15,7 +15,7 @@
       -- hypothesis
       h [theta0,theta1] x = theta0 + theta1 * x
       -- cost function
-      cost theta = mse [(realToFrac x, realToFrac y) | (x,y) <- samples] (h theta)
+      cost theta = mse [(auto x, auto y) | (x,y) <- samples] (h theta)
       params   = CG.defaultParameters{ CG.printFinal = True, CG.printParams = True, CG.verbose = CG.Verbose }
       grad_tol = 0.0000001
   (theta, result, stat) <- CG.optimize params grad_tol [0,0] cost
diff --git a/src/Numeric/Optimization/Algorithms/HagerZhang05/AD.hs b/src/Numeric/Optimization/Algorithms/HagerZhang05/AD.hs
--- a/src/Numeric/Optimization/Algorithms/HagerZhang05/AD.hs
+++ b/src/Numeric/Optimization/Algorithms/HagerZhang05/AD.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE ScopedTypeVariables, Rank2Types #-}
+{-# LANGUAGE ScopedTypeVariables, Rank2Types, FlexibleContexts, CPP #-}
 {-# OPTIONS_GHC -Wall #-}
 module Numeric.Optimization.Algorithms.HagerZhang05.AD
   ( -- * Main function
@@ -21,12 +21,19 @@
   ) where
 
 import Prelude hiding (mapM)
+import Control.Monad.Primitive
 import Data.Foldable (foldlM)
 import Data.Traversable (Traversable (..), mapAccumL, mapM)
 import qualified Data.Vector.Storable as S
 import qualified Data.Vector.Storable.Mutable as SM
 import Numeric.AD
-import Numeric.AD.Types
+#if MIN_VERSION_ad(4,0,0)
+import Data.Reflection (Reifies)
+import Numeric.AD.Mode.Reverse
+import Numeric.AD.Internal.Reverse (Tape)
+#else
+import Numeric.AD.Type
+#endif
 import Numeric.Optimization.Algorithms.HagerZhang05 hiding (optimize)
 import qualified Numeric.Optimization.Algorithms.HagerZhang05 as HagerZhang05
 
@@ -39,19 +46,22 @@
   => Parameters  -- ^ How should we optimize.
   -> Double      -- ^ @grad_tol@, see 'stopRules'.
   -> f Double    -- ^ Initial guess.
+#if MIN_VERSION_ad(4,0,0)
+--  -> (forall s. (Mode s, Scalar s ~ Double) => f s -> s) -- ^ Function to be minimized.
+  -> (forall s. Reifies s Tape => f (Reverse s Double) -> Reverse s Double) -- ^ Function to be minimized.
+#else
   -> (forall s. Mode s => f (AD s Double) -> AD s Double) -- ^ Function to be minimized.
+#endif
   -> IO (f Double, Result, Statistics)
 optimize params grad_tol initial f = do
   let size :: Int
       template :: f Int
       (size, template) = mapAccumL (\i _ -> i `seq` (i+1, i)) 0 initial
 
-      -- Some type signatures are commented out not to depend on 'primitive' package directly.
-
-      -- readFromMVec :: PrimMonad m => SM.MVector (PrimState m) Double -> m (f Double)
+      readFromMVec :: PrimMonad m => SM.MVector (PrimState m) Double -> m (f Double)
       readFromMVec mx  = mapM (SM.read mx) template
 
-      -- writeToMVec :: PrimMonad m => f Double -> SM.MVector (PrimState m) Double -> m ()
+      writeToMVec :: PrimMonad m => f Double -> SM.MVector (PrimState m) Double -> m ()
       writeToMVec x mx = do
         _ <- foldlM (\i v -> SM.write mx i v >> return (i+1)) 0 x
         return ()
@@ -59,17 +69,21 @@
       readFromVec :: S.Vector Double -> f Double
       readFromVec x = fmap (x S.!) template
 
-      -- mf :: forall m. (PrimMonad m, Functor m) => PointMVector m -> m Double
+      mf :: forall m. (PrimMonad m, Functor m) => PointMVector m -> m Double
       mf mx = do
         x <- readFromMVec mx
+#if MIN_VERSION_ad(4,0,0)
+        return $ fst $ grad' f x
+#else
         return $ lowerFU f x
+#endif
 
-      -- mg :: forall m. (PrimMonad m, Functor m) => PointMVector m -> GradientMVector m -> m ()
+      mg :: forall m. (PrimMonad m, Functor m) => PointMVector m -> GradientMVector m -> m ()
       mg mx mret = do
         x <- readFromMVec mx
         writeToMVec (grad f x) mret
 
-      -- mc :: (forall m. (PrimMonad m, Functor m) => PointMVector m -> GradientMVector m -> m Double)
+      mc :: (forall m. (PrimMonad m, Functor m) => PointMVector m -> GradientMVector m -> m Double)
       mc mx mret = do
         x <- readFromMVec mx
         let (y,g) = grad' f x
