diff --git a/.gitignore b/.gitignore
--- a/.gitignore
+++ b/.gitignore
@@ -5,3 +5,4 @@
 *.chi
 *.chs.h
 .virthualenv
+.stack-work
diff --git a/.travis.yml b/.travis.yml
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,55 +1,87 @@
-# NB: don't set `language: haskell` here
+language: c
+sudo: false
 
-# 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:
-# - GHCVER=6.12.3
-# - GHCVER=7.0.1
-# - GHCVER=7.0.2
-# - GHCVER=7.0.3
-# - GHCVER=7.0.4
-# - GHCVER=7.2.1
-# - GHCVER=7.2.2
-# - GHCVER=7.4.1
-# - GHCVER=7.4.2
-# - GHCVER=7.6.1
-# - GHCVER=7.6.2
- - GHCVER=7.6.3
-# - GHCVER=7.8.1 # see note about Alex/Happy
- - GHCVER=7.8.2 # see note about Alex/Happy
-# - GHCVER=head  # see section about GHC HEAD snapshots
+cache:
+  directories:
+    - $HOME/.cabsnap
+    - $HOME/.cabal/packages
 
-# Note: the distinction between `before_install` and `install` is not important.
+before_cache:
+  - rm -fv $HOME/.cabal/packages/hackage.haskell.org/build-reports.log
+  - rm -fv $HOME/.cabal/packages/hackage.haskell.org/00-index.tar
+
+matrix:
+  include:
+    - env: CABALVER=1.18 GHCVER=7.6.3
+      compiler: ": #GHC 7.6.3"
+      addons: {apt: {packages: [cabal-install-1.18,ghc-7.6.3,alex-3.1.4,happy-1.19.5], sources: [hvr-ghc]}}
+    - env: CABALVER=1.18 GHCVER=7.8.3 COVERAGE=1
+      compiler: ": #GHC 7.8.3"
+      addons: {apt: {packages: [cabal-install-1.18,ghc-7.8.3,alex-3.1.4,happy-1.19.5], sources: [hvr-ghc]}}
+    - env: CABALVER=1.22 GHCVER=7.10.3
+      compiler: ": #GHC 7.10.3"
+      addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.3,alex-3.1.4,happy-1.19.5], sources: [hvr-ghc]}}
+    - env: CABALVER=1.24 GHCVER=8.0.1
+      compiler: ": #GHC 8.0.1"
+      addons: {apt: {packages: [cabal-install-1.24,ghc-8.0.1,alex-3.1.4,happy-1.19.5], sources: [hvr-ghc]}}
+
 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-1.18 ghc-$GHCVER # see note about happy/alex
- - export PATH=/opt/ghc/$GHCVER/bin:/opt/cabal/1.18/bin:$PATH
- - |
-   if [ $GHCVER = "head" ] || [ ${GHCVER%.*} = "7.8" ]; then
-     travis_retry sudo apt-get install happy-1.19.3 alex-3.1.3
-     export PATH=/opt/alex/3.1.3/bin:/opt/happy/1.19.3/bin:$PATH
+ - unset CC
+ - export PATH=/opt/ghc/$GHCVER/bin:/opt/cabal/$CABALVER/bin:/opt/alex/3.1.4/bin:/opt/happy/1.19.5/bin:~/.cabal/bin:$PATH
+
+install:
+ - cabal --version
+ - echo "$(ghc --version) [$(ghc --print-project-git-commit-id 2> /dev/null || echo '?')]"
+ - if [ -f $HOME/.cabal/packages/hackage.haskell.org/00-index.tar.gz ];
+   then
+     zcat $HOME/.cabal/packages/hackage.haskell.org/00-index.tar.gz >
+          $HOME/.cabal/packages/hackage.haskell.org/00-index.tar;
+   fi
+ - travis_retry cabal update -v
+ - sed -i 's/^jobs:/-- jobs:/' ${HOME}/.cabal/config
+ - cabal install --only-dependencies --enable-tests --enable-benchmarks --dry -v > installplan.txt
+ - sed -i -e '1,/^Resolving /d' installplan.txt; cat installplan.txt
+
+# check whether current requested install-plan matches cached package-db snapshot
+ - if diff -u installplan.txt $HOME/.cabsnap/installplan.txt;
+   then
+     echo "cabal build-cache HIT";
+     rm -rfv .ghc;
+     cp -a $HOME/.cabsnap/ghc $HOME/.ghc;
+     cp -a $HOME/.cabsnap/lib $HOME/.cabsnap/share $HOME/.cabsnap/bin $HOME/.cabal/;
    else
-     travis_retry sudo apt-get install happy alex
+     echo "cabal build-cache MISS";
+     rm -rf $HOME/.cabsnap;
+     mkdir -p $HOME/.ghc $HOME/.cabal/lib $HOME/.cabal/share $HOME/.cabal/bin;
+     cabal install --only-dependencies --enable-tests --enable-benchmarks;
    fi
 
-install:
- - cabal update
- - cabal install --only-dependencies --enable-tests -v2  # -v2 provides useful information for debugging
+# snapshot package-db on cache miss
+ - if [ ! -d $HOME/.cabsnap ];
+   then
+      echo "snapshotting package-db to build-cache";
+      mkdir $HOME/.cabsnap;
+      cp -a $HOME/.ghc $HOME/.cabsnap/ghc;
+      cp -a $HOME/.cabal/lib $HOME/.cabal/share $HOME/.cabal/bin installplan.txt $HOME/.cabsnap/;
+   fi
 
-# 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.
+# 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:
- - cabal configure --enable-tests -v2  # -v2 provides useful information for debugging
+ - if [ -f configure.ac ]; then autoreconf -i; fi
+ - cabal configure --enable-tests --enable-benchmarks -v2 $([ "$COVERAGE" = "1" ] && echo "--enable-library-coverage") # -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-1.18 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;
-   fi
+# Check that the resulting source distribution can be built & installed.
+# If there are no other `.tar.gz` files in `dist`, this can be even simpler:
+# `cabal install --force-reinstalls dist/*-*.tar.gz`
+ - SRC_TGZ=$(cabal info . | awk '{print $2;exit}').tar.gz &&
+   (cd dist && cabal install --force-reinstalls "$SRC_TGZ")
+
+# This block must be executed before before_cache
+#after_script:
+ - "[ -n \"$COVERAGE\" ] && cabal install hpc-coveralls --avoid-reinstalls --constraint=\"regex-posix >=0.95.2\" || true" # regex-posix-0.95.1 has compilation problem
+ - "[ -n \"$COVERAGE\" ] && hpc-coveralls TestPrimeField --exclude-dir=test || true"
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
 finite-field
 ============
 
-[![Build Status](https://secure.travis-ci.org/msakai/finite-field.png?branch=master)](http://travis-ci.org/msakai/finite-field)
+[![Build Status](https://secure.travis-ci.org/msakai/finite-field.png?branch=master)](http://travis-ci.org/msakai/finite-field) [![Hackage](https://budueba.com/hackage/finite-field)](https://hackage.haskell.org/package/finite-field) [![Coverage Status](https://coveralls.io/repos/msakai/finite-field/badge.svg)](https://coveralls.io/r/msakai/finite-field)
diff --git a/finite-field.cabal b/finite-field.cabal
--- a/finite-field.cabal
+++ b/finite-field.cabal
@@ -1,5 +1,5 @@
 Name:		finite-field
-Version:	0.8.0
+Version:	0.9.0
 License:	BSD3
 License-File:	COPYING
 Author:		Masahiro Sakai (masahiro.sakai@gmail.com)
@@ -19,6 +19,11 @@
    .gitignore
 Build-Type: Simple
 
+Flag UseGHCTypeLits
+  Description: set GHC.TypeLits module
+  Default: True
+  Manual: True
+
 source-repository head
   type:     git
   location: git://github.com/msakai/finite-field.git
@@ -26,9 +31,15 @@
 Library
   Hs-source-dirs: src
   Build-Depends:
-     base >=4 && <5, template-haskell, deepseq, hashable, type-level-numbers >=0.1.1.0 && <0.2.0.0
+     base >=4 && <5, template-haskell, deepseq, hashable
+  if flag(UseGHCTypeLits)
+     Build-Depends: base >=4.7, singletons >=1.0
+     CPP-OPtions: "-DUseGHCTypeLits"
+  else
+     Build-Depends: type-level-numbers >=0.1.1.0 && <0.2.0.0
   Default-Language: Haskell2010
   Other-Extensions:
+     ConstraintKinds
      DeriveDataTypeable
      MultiParamTypeClasses
      ScopedTypeVariables
@@ -48,14 +59,24 @@
   Build-depends:
       base >=4 && <5,
       containers,
-      test-framework,
-      test-framework-th,
-      test-framework-hunit,
-      test-framework-quickcheck2,
-      HUnit,
-      QuickCheck >=2 && <3,
+      deepseq,
+      hashable,
+      tasty >=0.10.1,
+      tasty-hunit ==0.9.*,
+      tasty-quickcheck ==0.8.*,
+      tasty-th,
+      QuickCheck >=2.5 && <3,
       finite-field,
-      primes,
-      type-level-numbers >=0.1.1.0 && <0.2.0.0
+      primes
+  if flag(UseGHCTypeLits)
+     Build-Depends: base >=4.7, singletons >=1.0
+     CPP-OPtions: "-DUseGHCTypeLits"
+  else
+     Build-depends: type-level-numbers >=0.1.1.0 && <0.2.0.0
+  if impl(ghc<7.7)
+     Build-Depends: tagged
   Default-Language: Haskell2010
-  Other-Extensions: TemplateHaskell
+  Other-Extensions:
+      TemplateHaskell
+      ScopedTypeVariables
+      CPP
diff --git a/src/Data/FiniteField/PrimeField.hs b/src/Data/FiniteField/PrimeField.hs
--- a/src/Data/FiniteField/PrimeField.hs
+++ b/src/Data/FiniteField/PrimeField.hs
@@ -1,9 +1,10 @@
 {-# LANGUAGE ScopedTypeVariables, MultiParamTypeClasses, DeriveDataTypeable, TemplateHaskell, BangPatterns #-}
+{-# LANGUAGE CPP, KindSignatures, DataKinds, ConstraintKinds #-}
 {-# OPTIONS_GHC -Wall #-}
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Data.FiniteField.PrimeField
--- Copyright   :  (c) Masahiro Sakai 2013
+-- Copyright   :  (c) Masahiro Sakai 2013-2014
 -- License     :  BSD-style
 --
 -- Maintainer  :  masahiro.sakai@gmail.com
@@ -31,14 +32,26 @@
 import Data.Ratio (denominator, numerator)
 import Data.Typeable
 import qualified Language.Haskell.TH as TH
+#if !defined(UseGHCTypeLits)
 import qualified TypeLevel.Number.Nat as TL
+#else
+import GHC.TypeLits
+#endif
 import Data.FiniteField.Base
 
 -- | Finite field of prime order p, Fp = Z/pZ.
 --
 -- NB: Primality of @p@ is assumed, but not checked.
+#if !defined(UseGHCTypeLits)
 newtype PrimeField p = PrimeField Integer deriving (Eq, Typeable)
+#else
+newtype PrimeField (p::Nat) = PrimeField Integer deriving (Eq, Typeable)
+#endif
 
+#if !defined(UseGHCTypeLits)
+type KnownNat p = TL.Nat p
+#endif
+
 -- | conversion to 'Integer'
 toInteger :: PrimeField p -> Integer
 toInteger (PrimeField a) = a
@@ -49,36 +62,40 @@
 instance Show (PrimeField p) where
   showsPrec n (PrimeField x) = showsPrec n x
 
-instance TL.Nat p => Read (PrimeField p) where
+instance KnownNat p => Read (PrimeField p) where
   readsPrec n s = [(fromInteger a, s') | (a,s') <- readsPrec n s]
 
 instance NFData (PrimeField p) where
   rnf (PrimeField a) = rnf a
 
-instance TL.Nat p => Num (PrimeField p) where
+instance KnownNat p => Num (PrimeField p) where
   PrimeField a + PrimeField b = fromInteger $ a+b
   PrimeField a * PrimeField b = fromInteger $ a*b
   PrimeField a - PrimeField b = fromInteger $ a-b
   negate (PrimeField a)       = fromInteger $ negate a
   abs a         = a
   signum _      = 1
-  fromInteger a = PrimeField $ a `mod` TL.toInt (undefined :: p)
+  fromInteger a = ret
+    where
+      ret = PrimeField $ a `mod` char ret
 
-instance TL.Nat p => Fractional (PrimeField p) where
+instance KnownNat p => Fractional (PrimeField p) where
   fromRational r = fromInteger (numerator r) / fromInteger (denominator r)
---  recip a = a ^ (TL.toInt (undefined :: p) - 2 :: Integer)
-  recip (PrimeField a) =
+--  recip a = a ^ (char a - 2 :: Integer)
+  recip x@(PrimeField a) =
     case exgcd a p of
       (_, r, _) -> fromInteger r
     where
       p :: Integer
-      p = TL.toInt (undefined :: p)
+      p = char x
 
-instance TL.Nat p => Bounded (PrimeField p) where
+instance KnownNat p => Bounded (PrimeField p) where
   minBound = PrimeField 0
-  maxBound = PrimeField (TL.toInt (undefined :: p) - 1)
+  maxBound = ret
+    where
+      ret = PrimeField (char ret - 1)
 
-instance TL.Nat p => Enum (PrimeField p) where
+instance KnownNat p => Enum (PrimeField p) where
   toEnum x
     | toInt (minBound :: PrimeField p) <= x && x <= toInt (maxBound :: PrimeField p) = fromIntegral x
     | otherwise = error "PrimeField.toEnum: bad argument"
@@ -86,21 +103,23 @@
 
 instance Ord (PrimeField p) where
   PrimeField a `compare` PrimeField b = a `compare` b
-  PrimeField a `max` PrimeField b = PrimeField (a `max` b)
-  PrimeField a `min` PrimeField b = PrimeField (a `min` b)
 
-instance TL.Nat p => FiniteField (PrimeField p) where
-  order _   = TL.toInt (undefined :: p)
+instance KnownNat p => FiniteField (PrimeField p) where
+  order x   = char x
+#if !defined(UseGHCTypeLits)
   char _    = TL.toInt (undefined :: p)
+#else
+  char _    = natVal (Proxy :: Proxy p)
+#endif
   pthRoot a = a
   allValues = [minBound .. maxBound]
 
-instance TL.Nat p => Hashable (PrimeField p) where
-  hashWithSalt s (PrimeField a) =
-    s `hashWithSalt` (TL.toInt (undefined :: p) :: Int) `hashWithSalt` a
+instance KnownNat p => Hashable (PrimeField p) where
+  hashWithSalt s x@(PrimeField a) =
+    s `hashWithSalt` char x `hashWithSalt` a
 
 -- | Extended GCD algorithm
-exgcd :: (Eq a, Integral a) => a -> a -> (a, a, a)
+exgcd :: Integral a => a -> a -> (a, a, a)
 exgcd f1 f2 = f $ go f1 f2 1 0 0 1
   where
     go !r0 !r1 !s0 !s1 !t0 !t1
@@ -120,7 +139,11 @@
 primeField :: Integer -> TH.TypeQ
 primeField n
   | n <= 0    = error "primeField: negative value"
+#if !defined(UseGHCTypeLits)
   | otherwise = [t| PrimeField $(TL.natT n) |]
+#else
+  | otherwise = [t| PrimeField $(TH.litT (TH.numTyLit n)) |]
+#endif
 
 -- $TH
 -- Here is usage example for primeField:
diff --git a/test/TestPrimeField.hs b/test/TestPrimeField.hs
--- a/test/TestPrimeField.hs
+++ b/test/TestPrimeField.hs
@@ -1,83 +1,102 @@
-{-# LANGUAGE TemplateHaskell, ScopedTypeVariables #-}
+{-# LANGUAGE TemplateHaskell, ScopedTypeVariables, GADTs, DataKinds, CPP #-}
 {-# OPTIONS_GHC -fcontext-stack=32 #-}
 
-import Test.HUnit hiding (Test)
-import Test.QuickCheck
-import Test.Framework.TH
-import Test.Framework.Providers.QuickCheck2
-import Test.Framework.Providers.HUnit
+import Prelude hiding (toInteger)
 
+import Test.Tasty
+import Test.Tasty.QuickCheck
+import Test.Tasty.HUnit
+import Test.Tasty.TH
+import qualified Test.QuickCheck.Monadic as QM
+
+import Control.DeepSeq
+import Control.Exception
 import Control.Monad
+import Data.Either
+import Data.Hashable
 import Data.List (genericLength)
 import Data.Numbers.Primes (primes)
+import Data.Proxy
+import Data.Ratio
 
 import Data.FiniteField
+#ifdef UseGHCTypeLits
+import Data.Maybe
+import GHC.TypeLits
+#else
 import TypeLevel.Number.Nat
+#endif
 
 -- ----------------------------------------------------------------------
 -- addition
 
 prop_add_comm =
-  forAll smallPrimes $ \(SomeNat (_ :: p)) ->
+  forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) ->
     forAll arbitrary $ \(a :: PrimeField p) ->
     forAll arbitrary $ \b ->
       a + b == b + a
 
 prop_add_assoc =
-  forAll smallPrimes $ \(SomeNat (_ :: p)) ->
+  forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) ->
     forAll arbitrary $ \(a :: PrimeField p) ->
     forAll arbitrary $ \b ->
     forAll arbitrary $ \c ->
       (a + b) + c == a + (b + c)
 
 prop_add_unitl =
-  forAll smallPrimes $ \(SomeNat (_ :: p)) ->
+  forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) ->
     forAll arbitrary $ \(a :: PrimeField p) ->
       0 + a == a
 
 prop_add_unitr =
-  forAll smallPrimes $ \(SomeNat (_ :: p)) ->
+  forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) ->
     forAll arbitrary $ \(a :: PrimeField p) ->
       a + 0 == a
 
 prop_negate =
-  forAll smallPrimes $ \(SomeNat (_ :: p)) ->
+  forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) ->
     forAll arbitrary $ \(a :: PrimeField p) ->
       a + negate a == 0
 
+prop_sub_negate =
+  forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) ->
+    forAll arbitrary $ \(a :: PrimeField p) ->
+    forAll arbitrary $ \(b :: PrimeField p) ->
+      a - b == a + negate b
+
 -- ----------------------------------------------------------------------
 -- multiplication
 
 prop_mult_comm =
-  forAll smallPrimes $ \(SomeNat (_ :: p)) ->
+  forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) ->
     forAll arbitrary $ \(a :: PrimeField p) ->
     forAll arbitrary $ \b ->
       a * b == b * a
 
 prop_mult_assoc =
-  forAll smallPrimes $ \(SomeNat (_ :: p)) ->
+  forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) ->
     forAll arbitrary $ \(a :: PrimeField p) ->
     forAll arbitrary $ \b ->
     forAll arbitrary $ \c ->
       (a * b) * c == a * (b * c)
 
 prop_mult_unitl =
-  forAll smallPrimes $ \(SomeNat (_ :: p)) ->
+  forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) ->
     forAll arbitrary $ \(a :: PrimeField p) ->
       1 * a == a
 
 prop_mult_unitr =
-  forAll smallPrimes $ \(SomeNat (_ :: p)) ->
+  forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) ->
     forAll arbitrary $ \(a :: PrimeField p) ->
       a * 1 == a
 
 prop_mult_zero_l =
-  forAll smallPrimes $ \(SomeNat (_ :: p)) ->
+  forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) ->
     forAll arbitrary $ \(a :: PrimeField p) ->
       0*a == 0
 
 prop_mult_zero_r =
-  forAll smallPrimes $ \(SomeNat (_ :: p)) ->
+  forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) ->
         forAll arbitrary $ \(a :: PrimeField p) ->
           a*0 == 0
 
@@ -85,41 +104,111 @@
 -- distributivity
 
 prop_distl =
-  forAll smallPrimes $ \(SomeNat (_ :: p)) ->
+  forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) ->
     forAll arbitrary $ \(a :: PrimeField p) ->
     forAll arbitrary $ \b ->
     forAll arbitrary $ \c ->
       a * (b + c) == a*b + a*c
 
 prop_distr =
-  forAll smallPrimes $ \(SomeNat (_ :: p)) ->
+  forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) ->
     forAll arbitrary $ \(a :: PrimeField p) ->
     forAll arbitrary $ \b ->
     forAll arbitrary $ \c ->
       (b + c) * a == b*a + c*a
 
 -- ----------------------------------------------------------------------
--- recip
+-- misc Num methods
 
+prop_abs =
+  forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) ->
+    forAll arbitrary $ \(a :: PrimeField p) ->
+      abs a == a
+
+prop_signum =
+  forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) ->
+    forAll arbitrary $ \(a :: PrimeField p) ->
+      signum a == 1
+
+-- ----------------------------------------------------------------------
+-- Fractional
+
+prop_fromRational =
+  forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) ->
+    forAll arbitrary $ \(r :: Rational) ->
+      (fromRational r :: PrimeField p) == fromInteger (numerator r) / fromInteger (denominator r)
+
 prop_recip =
-  forAll smallPrimes $ \(SomeNat (_ :: p)) ->
+  forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) ->
     forAll arbitrary $ \(a :: PrimeField p) ->
       a /= 0 ==> a * (recip a) == 1
 
 -- ----------------------------------------------------------------------
--- FiniteField type class
+-- FiniteField
 
 prop_pthRoot =
-  forAll smallPrimes $ \(SomeNat (_ :: p)) ->
+  forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) ->
     forAll arbitrary $ \(a :: PrimeField p) ->
       pthRoot a ^ char a == a
 
 prop_allValues = do
-  forAll smallPrimes $ \(SomeNat (_ :: p)) ->
+  forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) ->
     genericLength (allValues :: [PrimeField p]) == order (undefined :: PrimeField p)
 
 -- ----------------------------------------------------------------------
+-- Show / Read
 
+prop_read_show =
+  forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) ->
+    forAll arbitrary $ \(a :: PrimeField p) ->
+      read (show a) == a  
+
+-- ----------------------------------------------------------------------
+-- Ord
+
+prop_zero_minimum =
+  forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) ->
+    forAll arbitrary $ \(a :: PrimeField p) ->
+      0 <= a
+
+-- ----------------------------------------------------------------------
+-- NFData
+
+prop_rnf =
+  forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) ->
+    forAll arbitrary $ \(a :: PrimeField p) ->
+      rnf a == ()
+
+-- ----------------------------------------------------------------------
+-- Enum
+
+prop_toEnum_fromEnum =
+  forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) ->
+    forAll arbitrary $ \(a :: PrimeField p) ->
+      toEnum (fromEnum a) == a
+
+prop_toEnum_negative = QM.monadicIO $ do
+  SomeNat' (_ :: Proxy p) <- QM.pick smallPrimes
+  let a :: PrimeField p
+      a = toEnum (-1)
+  (ret :: Either SomeException (PrimeField p)) <- QM.run $ try $ evaluate $ a
+  QM.assert $ isLeft ret
+
+-- ----------------------------------------------------------------------
+
+prop_hash =
+  forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) ->
+    forAll arbitrary $ \(a :: PrimeField p) ->
+      hash a `seq` () == ()
+
+-- ----------------------------------------------------------------------
+-- misc
+
+prop_fromInteger_toInteger =
+  forAll smallPrimes $ \(SomeNat' (_ :: Proxy p)) ->
+    forAll arbitrary $ \(a :: PrimeField p) ->
+      fromInteger (toInteger a) == a
+
 case_primeFieldT = a @?= 1
   where
     a :: $(primeField 15485867)
@@ -127,12 +216,41 @@
 
 ------------------------------------------------------------------------
 
-smallPrimes :: Gen SomeNat
+#ifdef UseGHCTypeLits
+
+data SomeNat' where
+  SomeNat' :: KnownNat p => Proxy p -> SomeNat'
+
+instance Show SomeNat' where
+  showsPrec p (SomeNat' x) = showsPrec p (natVal x)
+
+#else
+
+data SomeNat' where
+  SomeNat' :: Nat p => Proxy p -> SomeNat'
+
+instance Show SomeNat' where
+  showsPrec p (SomeNat' (x :: Proxy p)) = showsPrec p (toInt (undefined :: p))
+
+#endif
+
+smallPrimes :: Gen SomeNat'
 smallPrimes = do
   i <- choose (0, 2^(16::Int))
-  return $ withNat SomeNat (primes !! i)
+#ifdef UseGHCTypeLits
+  case fromJust $ someNatVal $ primes !! i of
+    SomeNat proxy -> return $ SomeNat' proxy
+#else
+  let f :: forall p. Nat p => p -> SomeNat'
+      f _ = SomeNat' (Proxy :: Proxy p)
+  return $ withNat f (primes !! i)
+#endif
 
+#ifdef UseGHCTypeLits
+instance KnownNat p => Arbitrary (PrimeField p) where
+#else
 instance Nat p => Arbitrary (PrimeField p) where
+#endif
   arbitrary = liftM fromInteger arbitrary
 
 ------------------------------------------------------------------------
@@ -140,3 +258,15 @@
 
 main :: IO ()
 main = $(defaultMainGenerator)
+
+#if !MIN_VERSION_base(4,7,0)
+
+isLeft :: Either a b -> Bool
+isLeft (Left  _) = True
+isLeft (Right _) = False
+
+isRight :: Either a b -> Bool
+isRight (Left  _) = False
+isRight (Right _) = True
+
+#endif
