diff --git a/Math/MFSolve.hs b/Math/MFSolve.hs
--- a/Math/MFSolve.hs
+++ b/Math/MFSolve.hs
@@ -114,12 +114,48 @@
 import Data.List
 import Data.Function(on)
 
-data BinaryOp = Add | Mul
-              deriving Eq
+data BinaryOp =
+  -- | Addition
+  Add |
+  -- | Multiplication
+  Mul
+  deriving Eq
+
 data UnaryOp =
-  Sin | Abs | Recip | Signum |
-  Exp | Log | Cos | Cosh | Atanh |
-  Tan | Sinh | Asin | Acos | Asinh | Acosh | Atan
+  -- | sine
+  Sin |
+  -- | cosine
+  Cos |
+  -- | absolute value
+  Abs |
+  -- | reciprocal (1/x)
+  Recip |
+  -- | sign
+  Signum |
+  -- | natural exponential (e^x)
+  Exp |
+  -- | natural logarithm (log x)
+  Log |
+  -- | hyperbolic cosine
+  Cosh |
+  -- | inverse hyperbolic tangent
+  Atanh |
+  -- | tangent
+  Tan |
+  -- | hyperbolic tangent
+  Tanh |
+  -- | hyperbolic sine
+  Sinh |
+  -- | inverse sine
+  Asin |
+  -- | inverse cosine
+  Acos |
+  -- | inverse hyperbolic sine
+  Asinh |
+  -- | inverse hyperbolic cosine
+  Acosh |
+  -- | inverse tangent
+  Atan
   deriving (Eq, Generic)
 
 -- | A simplified datatype representing an expression.  This can be
@@ -213,13 +249,13 @@
   -- | The equation was reduced to the
   -- impossible equation `a == 0` for nonzero a, which means the
   -- equation is inconsistent with previous equations.
-  InconsistentEq n |
+  InconsistentEq n (Expr v n) |
   -- | The equation was reduced to the redundant equation `0 == 0`,
   -- which means it doesn't add any information.
-  RedundantEq
+  RedundantEq (Expr v n)
   deriving Typeable
 
-instance (Show v, Show n, Typeable v, Typeable n) => Exception (DepError v n)
+instance (Ord n, Num n, Show v, Show n, Typeable v, Typeable n) => Exception (DepError v n)
 
 instance (Ord n, Num n, Eq n, Show v, Show n) => Show (Expr v n) where
   show e = show (toSimple e)
@@ -277,6 +313,7 @@
   show Cosh = "cosh"
   show Atanh = "atanh"
   show Tan = "tan"
+  show Tanh = "tanh"
   show Sinh = "sinh"
   show Asin = "asin"
   show Acos = "acos"
@@ -305,6 +342,7 @@
   cosh = unExpr Cosh
   atanh = unExpr Atanh
   tan = unExpr Tan
+  tanh = unExpr Tanh
   sinh = unExpr Sinh
   asin = unExpr Asin
   acos = unExpr Acos
@@ -319,11 +357,12 @@
     where showLin (v, e) = show v ++ " = " ++ show (LinearE e)
           showNl e = show e ++ " = 0"
 
-instance (Show n, Show v) => Show (DepError v n) where
-  show (InconsistentEq a) =
-    "Inconsistent equations, off by " ++ show a
-  show RedundantEq =
-    "Redundant Equation."
+instance (Num n, Ord n, Show n, Show v) => Show (DepError v n) where
+  show (InconsistentEq a e) =
+    "Inconsistent equations, off by " ++ show a ++
+    ".  original expression: " ++ show e
+  show (RedundantEq e) =
+    "Redundant Equation: " ++ show e
   show (UndefinedVar v) =
     error ("Variable is undefined: " ++ show v)
   show (UnknownVar v n) =
@@ -396,6 +435,7 @@
 evalUn Cosh = cosh
 evalUn Atanh = atanh
 evalUn Tan = tan
+evalUn Tanh = tanh
 evalUn Sinh = sinh
 evalUn Asin = asin
 evalUn Acos = acos
@@ -437,6 +477,9 @@
 zeroTerm :: (Num n) => LinExpr v n
 zeroTerm = LConst 0
 
+zeroExpr :: (Num n) => Expr v n
+zeroExpr = makeConstant 0
+
 -- | Create an expression from a constant
 makeConstant :: n -> Expr v n
 makeConstant = ConstE
@@ -643,7 +686,7 @@
          Dependencies v n
          -> Expr v n -> Either (DepError v n) (Dependencies v n)
 addEquation deps@(Dependencies _ lin _ _ _) expr =
-  addEq0 deps $
+  addEq0 deps expr $
   -- substitute known and dependend variables
   subst (flip M.lookup lin) expr
   
@@ -709,14 +752,16 @@
               (H.fromList $ linVars lt)
   in (vdep', lin')
 
-addEq0 :: (Hashable v, Hashable n, RealFrac (Phase n), Ord v, Floating n) => Dependencies v n -> Expr v n -> Either (DepError v n) (Dependencies v n)
+addEq0 :: (Hashable v, Hashable n, RealFrac (Phase n), Ord v, Floating n) => Dependencies v n -> Expr v n -> Expr v n -> Either (DepError v n) (Dependencies v n)
 -- adding a constant equation
-addEq0 _  (ConstE c) =
-  Left $ if c == 0 then RedundantEq
-         else InconsistentEq c
+addEq0 _ e (ConstE c) =
+  Left $ if abs c < eps
+         then RedundantEq e
+         else InconsistentEq c e
+  where eps = 0.0001
 
 -- adding a linear equation
-addEq0 (Dependencies vdep lin trig trig2 nonlin) (Expr lt [] []) =
+addEq0 (Dependencies vdep lin trig trig2 nonlin) _ (Expr lt [] []) =
   let (v, _, lt2) = splitMax lt
       (vdep', lin') = substDep vdep lin v lt2 True
       
@@ -726,11 +771,11 @@
   in addEqs (Dependencies vdep' lin' [] M.empty []) (trig'++trig2'++nonlin)
 
 -- adding a sine equation
-addEq0 deps@(Dependencies vdep lin trig trig2 nl)
+addEq0 deps@(Dependencies vdep lin trig trig2 nl) orig
   (Expr (LinExpr c lt) [(theta, [(alpha, LConst n)])] []) =
   if null lt then
     -- reduce a sine to linear equation
-    addEq0 deps (LinearE $ LinExpr (alpha - asin (-c/n)) theta)
+    addEq0 deps orig (LinearE $ LinExpr (alpha - asin (-c/n)) theta)
   else
     -- add a variable dependency on the sine equation
     case M.lookup theta trig2 of
@@ -745,7 +790,7 @@
         Expr lt2 [(_, [(alpha2, LConst n2)])] []
           | not $ isConst lt2
           -> addSin lt2 alpha2 n2
-        e2 -> addEq0 deps e2
+        e2 -> addEq0 deps orig e2
        where
          doSubst (v,c2) = case M.lookup v map2 of
            Nothing -> makeVariable v * ConstE c2
@@ -760,12 +805,12 @@
       in Right $ Dependencies  vdep lin trig trig2' nl
 
 --  adding the first sine equation
-addEq0 (Dependencies d lin [] trig2 nl)
+addEq0 (Dependencies d lin [] trig2 nl) _
   (Expr (LConst c) [(theta, [(alpha, n)])] []) =
   Right $ Dependencies d lin [(theta, n, alpha, c)] trig2 nl
 
 -- try reducing this equation with another sine equation
-addEq0 (Dependencies deps lin trig trig2 nl)
+addEq0 (Dependencies deps lin trig trig2 nl) _
   (Expr (LConst x) [(theta, [(a, n)])] []) =
   case mapMaybe similarTrig $ select trig of
    -- no matching equation found
@@ -793,7 +838,7 @@
       | otherwise = Nothing
 
 -- just add any other equation to the list of nonlinear equations
-addEq0 (Dependencies d lin trig trig2 nonlin) e =
+addEq0 (Dependencies d lin trig trig2 nonlin) _ e =
   Right $ Dependencies d lin trig trig2 (e:nonlin)
 
 deleteDep :: (Hashable k, Hashable b, Eq k, Eq b) =>
@@ -841,7 +886,7 @@
              deps = Dependencies vdep'' lin'' [] M.empty []
              e = [LinearE lt2 - makeVariable v]
           -- use addEq0 since substitution is unnecessary
-         in case foldM addEq0
+         in case foldM (flip addEq0 zeroExpr)
                  deps $
                  map (subst $ simpleSubst v lt2)
                  (trig'++trig2'++nonlin) of
@@ -861,7 +906,7 @@
             partition (hasVar v) $
             map trigToExpr trig ++ nonlin
           deps = Dependencies vdep lin [] trig2' []
-      in case foldM addEq0 deps
+      in case foldM (flip addEq0 zeroExpr) deps
               nlWithout of
              Left _ -> (deps, nlWith++l) --shouldn't happen
              Right d -> (d, nlWith++l)
@@ -1043,7 +1088,7 @@
 (=&=) (a, b) (c, d) =
   do catchError (a === c) $ \e ->
        case e of
-        RedundantEq ->
+        RedundantEq _ ->
           b === d
         _ -> throwError e
      ignore $ b === d
@@ -1053,7 +1098,7 @@
 ignore m =
   catchError m $ \e ->
   case e of
-   RedundantEq -> return ()
+   RedundantEq _ -> return ()
    _ -> throwError e
 
 -- | run the solver.
@@ -1061,7 +1106,7 @@
 runSolver s = runIdentity . runSolverT s
            
 -- | Return the result of solving the equations, or throw the error as an exception.  Monadic version.
-unsafeSolveT :: (Show n, Show v, Typeable n, Typeable v, Monad m) =>
+unsafeSolveT :: (Num n, Ord n, Show n, Show v, Typeable n, Typeable v, Monad m) =>
                 Dependencies v n -> MFSolverT v n m a -> m a
 unsafeSolveT dep s = do
   res <- runSolverT s dep
@@ -1084,7 +1129,7 @@
   fmap snd <$> runSolverT s dep
 
 -- | Return the result of solving the equations, or throw the error as an exception.
-unsafeSolve :: (Typeable n, Typeable v, Show n, Show v) =>
+unsafeSolve :: (Typeable n, Typeable v, Show n, Show v, Ord n, Num n) =>
                Dependencies v n -> MFSolver v n a -> a
 unsafeSolve dep = runIdentity . unsafeSolveT dep
 
diff --git a/mfsolve.cabal b/mfsolve.cabal
--- a/mfsolve.cabal
+++ b/mfsolve.cabal
@@ -1,5 +1,5 @@
 Name:		mfsolve
-Version: 	0.3.1.2
+Version: 	0.3.2.0
 Synopsis:	Equation solver and calculator à la metafont
 Category: 	Math
 Copyright: 	Kristof Bastiaensen (2015)
@@ -21,7 +21,7 @@
 
 Library
   Ghc-options: -Wall
-  Build-depends: base >= 3 && < 5, unordered-containers > 0.2, hashable >= 0.1.2, mtl >= 2.1.3
+  Build-depends: base >= 3 && < 5, unordered-containers > 0.2, hashable >= 0.1.2, mtl >= 2.1.3, mtl-compat >= 0.2.1
   Exposed-Modules:
     Math.MFSolve
   extensions: DeriveGeneric, PatternGuards, PatternSynonyms
diff --git a/tests/test.hs b/tests/test.hs
--- a/tests/test.hs
+++ b/tests/test.hs
@@ -104,13 +104,13 @@
 
 solveOne :: [TestEq] -> String
 solveOne eqs =  
-  case solveEqs noDeps $
-       map (flip addEquation . uncurry (-) . snd) eqs
+  case flip execSolver noDeps $
+       mapM (uncurry (===) . snd) eqs
   of
-   Left RedundantEq ->
-     "Found redundant equation"
-   Left (InconsistentEq n) ->
-     "Equation off by "++ show n
+   Left (RedundantEq e) ->
+     "Found redundant equation.  Last equation: " ++ show e
+   Left (InconsistentEq n e) ->
+     "Equation off by "++ show n ++ ".  Last equation: " ++ show e
    Right d
      | not $ null $ nonlinearEqs d ->
        "Some nonlinear equations were unevaluated:\n" ++
