diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,13 +1,21 @@
-* v 0.1
-  * first release
+* v 0.3 2017-08-01
+  * renamed the main module to MixedTypesNumPrelude
+  * much faster compilation
+  * Ring and Field are now classes, not synonyms for large sets of constraints
+  * many fixes in collect-error framework and its use in division and power
+  * Overloaded if-then-else via -XRebindableSyntax
+  * compiling with ghc 8.2.1
 
+* v 0.2.0.1
+  * fix compilation bug in test suite
+  * minor doc improvements
+  * fix Complex instances of error-throwing division (/!)
+
 * v 0.2
   * new CollectErrors wrapper
   * CN, specialisation of CollectErrors to NumErrors
   * numerical partial operators (eg division) return a CN type
   * instances for Data.Complex
 
-* v 0.2.0.1
-  * fix compilation bug in test suite
-  * minor doc improvements
-  * fix Complex instances of error-throwing division (/!)
+* v 0.1
+  * first release
diff --git a/mixed-types-num.cabal b/mixed-types-num.cabal
--- a/mixed-types-num.cabal
+++ b/mixed-types-num.cabal
@@ -1,5 +1,5 @@
 name:           mixed-types-num
-version:        0.2.0.1
+version:        0.3
 cabal-version:  >= 1.9.2
 build-type:     Simple
 homepage:       https://github.com/michalkonecny/mixed-types-num
@@ -10,7 +10,7 @@
 license-file:   LICENSE
 extra-source-files:  changelog.md
 stability:      experimental
-tested-with:    GHC==7.10.3, GHC==8.0.2
+tested-with:    GHC==7.10.3, GHC==8.0.2, GHC==8.2.1
 category:       Math
 synopsis:       Alternative Prelude with numeric and logic expressions typed bottom-up
 Description:
@@ -28,11 +28,10 @@
   type:     git
   location: https://github.com/mikkonecny/mixed-types-num
 
-
 library
   hs-source-dirs:  src
   build-depends:
-    base >= 4.8 && < 4.10
+    base >= 4.8 && < 4.11
     , convertible >= 1.1.1.0 && < 1.2
     , template-haskell
     , hspec >= 2.1 && < 2.5
diff --git a/src/Control/CollectErrors.hs b/src/Control/CollectErrors.hs
--- a/src/Control/CollectErrors.hs
+++ b/src/Control/CollectErrors.hs
@@ -3,6 +3,7 @@
 (
 -- * Monad for collecting errors in expressions
   CollectErrors(..), SuitableForCE
+, CanTestErrorsCertain(..), hasCertainErrorCE
 , noValueCE, prependErrorsCE
 , filterValuesWithoutErrorCE, getValueIfNoErrorCE
 , ce2ConvertResult
@@ -10,16 +11,22 @@
 , CanEnsureCE(..)
 , getValueOrThrowErrorsNCE
 , lift1CE, lift2CE, lift2TCE, lift2TLCE
+-- ** Tools for pulling errors out of structures
+, CanExtractCE(..)
 )
 where
 
 import Prelude
-  (Functor(..), Applicative(..), Monad(..), (<$>), ($)
-  , id, error, const, flip
+  (Functor(..), Applicative(..), Monad(..), (<$>), ($), (.)
+  , error, const, flip, not, fst, snd, foldMap, (++)
   , Int, Integer, Rational, Double, Bool, Char
   , Maybe(..), Either(..)
-  , Show(..), Eq(..))
+  , Show(..), Eq(..)
+  , Traversable(..))
 import Text.Printf
+
+import Control.Monad (join)
+
 import Data.Monoid
 import Data.Maybe (fromJust)
 
@@ -47,13 +54,20 @@
     { getMaybeValueCE :: Maybe v
     , getErrorsCE :: es }
 
-type SuitableForCE es = (Monoid es, Eq es, Show es)
+class CanTestErrorsCertain es where
+  hasCertainError :: es -> Bool
 
+hasCertainErrorCE :: (CanTestErrorsCertain es) => (CollectErrors es v) -> Bool
+hasCertainErrorCE (CollectErrors _ es) = hasCertainError es
+
+type SuitableForCE es = (Monoid es, Eq es, Show es, CanTestErrorsCertain es)
+
 instance (Show v, SuitableForCE es) => (Show (CollectErrors es v)) where
   show (CollectErrors mv es) =
     case mv of
       Just v | es == mempty -> show v
-      _ -> printf "{%s}" (show es)
+      Just v -> printf "%s{%s}" (show v) (show es)
+      Nothing -> printf "{%s}" (show es)
 
 noValueCE :: es -> CollectErrors es v
 noValueCE es = CollectErrors Nothing es
@@ -121,7 +135,14 @@
   the shape of the type, especially whether
   it already has CollectErrors.
 -}
-class (Monoid es) => CanEnsureCE es a where
+class
+  (Monoid es
+  , EnsureCE es (EnsureCE es a) ~ EnsureCE es a
+  , EnsureCE es (EnsureNoCE es a) ~ EnsureCE es a
+  , EnsureNoCE es (EnsureCE es a) ~ EnsureNoCE es a
+  , EnsureNoCE es (EnsureNoCE es a) ~ EnsureNoCE es a)
+  =>
+  CanEnsureCE es a where
   {-|
     Add CollectErrors to a type except when the type already
     has CollectErrors in it.
@@ -161,13 +182,13 @@
 
   ensureNoCE ::
     Maybe es {-^ sample only -} ->
-    a -> Either es (EnsureNoCE es a)
+    a -> (Maybe (EnsureNoCE es a), es)
 
   default ensureNoCE ::
-    (EnsureNoCE es a ~ a, Eq es) =>
+    (EnsureNoCE es a ~ a, Eq es, Monoid es) =>
     Maybe es {-^ sample only -} ->
-    a -> Either es (EnsureNoCE es a)
-  ensureNoCE _ = Right
+    a -> (Maybe (EnsureNoCE es a), es)
+  ensureNoCE _ a = (Just a, mempty)
 
   {-|  Make CollectErrors record with no value, only errors. -}
   noValueECE ::
@@ -178,27 +199,47 @@
     (EnsureCE es a ~ CollectErrors es a)
     =>
     Maybe a ->
-    es -> CollectErrors es a
+    es -> EnsureCE es a
   noValueECE _ = noValueCE
 
+  prependErrorsECE ::
+    Maybe a ->
+    es -> EnsureCE es a -> EnsureCE es a
+  default prependErrorsECE ::
+    (EnsureCE es a ~ CollectErrors es a)
+    =>
+    Maybe a ->
+    es -> EnsureCE es a -> EnsureCE es a
+  prependErrorsECE _ = prependErrorsCE
+
 -- instance for CollectErrors a:
 
 instance
-  (SuitableForCE es)
+  (SuitableForCE es, CanEnsureCE es a)
   =>
   CanEnsureCE es (CollectErrors es a)
   where
-  type EnsureCE es (CollectErrors es a) = CollectErrors es a
-  type EnsureNoCE es (CollectErrors es a) = a
+  type EnsureCE es (CollectErrors es a) = EnsureCE es a
+  type EnsureNoCE es (CollectErrors es a) = EnsureNoCE es a
 
-  ensureCE _sample_es = id
-  deEnsureCE _sample_es = Right
-  ensureNoCE _sample_es (CollectErrors mv es) =
+  ensureCE sample_es (CollectErrors mv es) =
     case mv of
-    Just v | es == mempty -> Right v
-    _ -> Left es
+      Just v -> prependErrorsECE (Just v) es $ ensureCE sample_es v
+      _ -> noValueECE mv es
+  deEnsureCE sample_es vCE =
+    case deEnsureCE sample_es vCE of
+      Right v -> Right $ CollectErrors (Just v) mempty
+      Left es -> Left es
+  ensureNoCE sample_es (CollectErrors mv es) =
+    case fmap (ensureNoCE sample_es) mv of
+      Just (Just v, es2) -> (Just v, es2 <> es)
+      Just (_, es2) -> (Nothing, es2 <> es)
+      _ -> (Nothing, mempty)
 
-  noValueECE _sample_vCE es = CollectErrors Nothing es
+  noValueECE sample_vCE es =
+    noValueECE (join $ fmap getMaybeValueCE sample_vCE) es
+  prependErrorsECE sample_vCE =
+    prependErrorsECE (join $ fmap getMaybeValueCE sample_vCE)
 
 -- instances for ground types, using the default implementations:
 
@@ -223,11 +264,45 @@
   ensureCE sample_es = fmap (ensureCE sample_es)
   deEnsureCE sample_es (Just vCE) = fmap Just (deEnsureCE sample_es vCE)
   deEnsureCE _sample_es Nothing = Right Nothing
-  ensureNoCE sample_es (Just vCE) = fmap Just (ensureNoCE sample_es vCE)
-  ensureNoCE _sample_es Nothing = Right Nothing
+  ensureNoCE sample_es (Just vCE) =
+    case ensureNoCE sample_es vCE of
+      (Just v, es) -> (Just (Just v), es)
+      (_, es) -> (Nothing, es)
+  ensureNoCE _sample_es Nothing = (Nothing, mempty)
 
   noValueECE sample_vCE es = Just (noValueECE (fromJust sample_vCE) es)
 
+  prependErrorsECE sample_vCE es (Just vCE) =
+    Just $ prependErrorsECE (fromJust sample_vCE) es vCE
+  prependErrorsECE _sample_vCE _es Nothing = Nothing
+
+instance
+  (SuitableForCE es, CanEnsureCE es a)
+  =>
+  CanEnsureCE es (b -> a)
+  where
+  type EnsureCE es (b -> a) = b -> (EnsureCE es a)
+  type EnsureNoCE es (b -> a) = b ->  (EnsureNoCE es a)
+
+  ensureCE sample_es = ((ensureCE sample_es) .)
+  deEnsureCE sample_es f =
+    Right $ \ a ->
+      case deEnsureCE sample_es (f a) of
+        Right v -> v
+        Left es -> error $ "deEnsureCE for function: " ++ show es
+  ensureNoCE sample_es f = (Just f', mempty)
+    where
+    f' a =
+      case ensureNoCE sample_es (f a) of
+        (Just v, _) -> v
+        (_, es) -> error $ "ensureNoCE for function: " ++ show es
+
+  noValueECE (_fvCE :: Maybe (b -> a)) es =
+    const (noValueECE (Nothing :: Maybe a) es)
+
+  prependErrorsECE (_fvCE :: Maybe (b -> a)) es =
+    ((prependErrorsECE (Nothing :: Maybe a) es) .)
+
 -- instance (Monoid es) => CanEnsureCE es [a] where
 -- instance (Monoid es) => CanEnsureCE es (Either e a) where
 
@@ -239,8 +314,8 @@
   v -> (EnsureNoCE es v)
 getValueOrThrowErrorsNCE sample_es v =
   case ensureNoCE sample_es v of
-    Right vNCE -> vNCE
-    Left es -> error (show es)
+    (Just vNCE, es) | not (hasCertainError es) -> vNCE
+    (_, es) -> error (show es)
 
 {-|
   Add error collection support to an unary function whose
@@ -248,17 +323,19 @@
 -}
 lift1CE ::
   (SuitableForCE es
-  , CanEnsureCE es c)
+  , CanEnsureCE es a, CanEnsureCE es c)
   =>
   (a -> c) ->
   (CollectErrors es a) -> (EnsureCE es c)
-lift1CE (fn :: a -> c) aCE =
-  case (ensureNoCE sample_es aCE) of
-    Right a -> ensureCE sample_es $ fn a
-    _ -> noValueECE sample_c a_es
+lift1CE fn aCE =
+  case ma of
+    Just a ->
+      prependErrorsECE sample_c a_es $ ensureCE sample_es $ fn a
+    _ ->
+      noValueECE sample_c a_es
   where
-  sample_es = Just a_es
   CollectErrors ma a_es = aCE
+  sample_es = Just a_es
   sample_c = fn <$> ma
 
 {-|
@@ -267,18 +344,21 @@
 -}
 lift2CE ::
   (SuitableForCE es
-  , CanEnsureCE es c)
+  , CanEnsureCE es a, CanEnsureCE es b, CanEnsureCE es c)
   =>
   (a -> b -> c) ->
   (CollectErrors es a) -> (CollectErrors es b) -> (EnsureCE es c)
-lift2CE (fn :: a -> b -> c) aCE bCE =
-  case (ensureNoCE sample_es aCE, ensureNoCE sample_es bCE) of
-    (Right a, Right b) -> ensureCE sample_es $ fn a b
-    _ -> noValueECE sample_c (a_es <> b_es)
+lift2CE fn aCE bCE =
+  case (ma, mb) of
+    (Just a, Just b) ->
+      prependErrorsECE sample_c ab_es $ ensureCE sample_es $ fn a b
+    _ ->
+      noValueECE sample_c ab_es
   where
-  sample_es = Just a_es
   CollectErrors ma a_es = aCE
   CollectErrors mb b_es = bCE
+  ab_es = a_es <> b_es
+  sample_es = Just a_es
   sample_c = fn <$> ma <*> mb
 
 {-|
@@ -288,17 +368,19 @@
 -}
 lift2TCE ::
   (SuitableForCE es
-  , CanEnsureCE es c)
+  , CanEnsureCE es a, CanEnsureCE es c)
   =>
   (a -> b -> c) ->
   (CollectErrors es a) -> b -> (EnsureCE es c)
-lift2TCE (fn :: a -> b -> c) aCE b =
-  case (ensureNoCE sample_es aCE) of
-    (Right a) -> ensureCE sample_es $ fn a b
-    _ -> noValueECE sample_c a_es
+lift2TCE fn aCE b =
+  case ma of
+    (Just a) ->
+      prependErrorsECE sample_c a_es $ ensureCE sample_es $ fn a b
+    _ ->
+      noValueECE sample_c a_es
   where
-  sample_es = Just a_es
   CollectErrors ma a_es = aCE
+  sample_es = Just a_es
   sample_c = fn <$> ma <*> (Just b)
 
 {-|
@@ -308,8 +390,31 @@
 -}
 lift2TLCE ::
   (SuitableForCE es
-  , CanEnsureCE es c)
+  , CanEnsureCE es b, CanEnsureCE es c)
   =>
   (a -> b -> c) ->
   a -> (CollectErrors es b) -> (EnsureCE es c)
 lift2TLCE f = flip $ lift2TCE (flip f)
+
+
+{-|
+  Ability to lift collected (potential) errors from inside some structure/collection.
+
+  This is useful mostly for structures that use the default implementation of
+  'CanEnsureCE es'.
+-}
+class (SuitableForCE es) => CanExtractCE es f where
+  extractCE ::
+    (CanEnsureCE es c) =>
+    Maybe es ->
+    f c -> CollectErrors es (f (EnsureNoCE es c))
+  default extractCE ::
+    (CanEnsureCE es c, Traversable f) =>
+    Maybe es ->
+    f c -> CollectErrors es (f (EnsureNoCE es c))
+  extractCE sample_es fc =
+    case mapM fst fcNoCE of
+      Just fec -> pure fec
+      _ -> noValueCE $ foldMap snd fcNoCE
+    where
+    fcNoCE = fmap (ensureNoCE sample_es) fc
diff --git a/src/Numeric/CollectErrors.hs b/src/Numeric/CollectErrors.hs
--- a/src/Numeric/CollectErrors.hs
+++ b/src/Numeric/CollectErrors.hs
@@ -12,22 +12,26 @@
 -}
 module Numeric.CollectErrors
 (
-  -- * Describing numeric errors
+  -- * Type of numeric errors
   ErrorCertaintyLevel(..), NumError(..), NumErrors, sample_NumErrors
   -- * Specialisation to numeric errors
-, CN, CanEnsureCN, EnsureCN, EnsureNoCN
-, ensureCN, deEnsureCN, ensureNoCN
+, CN
+, hasCertainError, hasCertainErrorCN
 , noValueCN
 , noValueNumErrorCertainCN, noValueNumErrorPotentialCN
 , getMaybeValueCN, getErrorsCN, prependErrorsCN
-, noValueECN
+, CanEnsureCN, EnsureCN, EnsureNoCN
+, ensureCN, deEnsureCN, ensureNoCN
+, noValueECN, prependErrorsECN
 , noValueNumErrorCertainECN, noValueNumErrorPotentialECN
+, CanExtractCN, extractCN
   -- ** More compact synonyms
 , cn, deCN, (~!)
 )
 where
 
-import Prelude (Show(..), Eq(..), String, Maybe(..), Either(..), (++))
+import Prelude
+  (Show(..), Eq(..), Bool, String, Maybe(..), Either(..), (++), (.), or, map, fst, ($))
 
 import Control.CollectErrors
 
@@ -50,6 +54,13 @@
 
 type NumErrors = [(ErrorCertaintyLevel, NumError)]
 
+instance CanTestErrorsCertain NumErrors where
+  hasCertainError es =
+    or $ map ((== ErrorCertain) . fst) es
+
+hasCertainErrorCN :: CN v -> Bool
+hasCertainErrorCN = hasCertainErrorCE
+
 sample_NumErrors :: Maybe [(ErrorCertaintyLevel, NumError)]
 sample_NumErrors = Nothing
 
@@ -58,6 +69,12 @@
 type EnsureCN a = EnsureCE NumErrors a
 type EnsureNoCN a = EnsureNoCE NumErrors a
 
+type CanExtractCN f = CanExtractCE NumErrors f
+extractCN ::
+  (CanEnsureCN c, CanExtractCN f) =>
+  f c -> CN (f (EnsureNoCN c))
+extractCN = extractCE sample_NumErrors
+
 {-|
   Translate a value of a type @a@
   to a value of a type @CollectNumErrors a@ except when @a@
@@ -79,11 +96,14 @@
   to a value of a type @CollectNumErrors a@ except when @a@
   already is a @CollectNumErrors@ type, in which case the value is left as is.
 -}
-ensureNoCN :: (CanEnsureCN v) => v -> Either NumErrors (EnsureNoCN v)
+ensureNoCN :: (CanEnsureCN v) => v -> (Maybe (EnsureNoCN v), NumErrors)
 ensureNoCN = ensureNoCE sample_NumErrors
 
 noValueECN :: (CanEnsureCN v) => Maybe v -> NumErrors -> EnsureCN v
 noValueECN = noValueECE
+
+prependErrorsECN :: (CanEnsureCN v) => Maybe v -> NumErrors -> EnsureCN v -> EnsureCN v
+prependErrorsECN = prependErrorsECE
 
 {-| Construct an empty wrapper indicating that given error has certainly occurred. -}
 noValueNumErrorCertainECN :: (CanEnsureCN v) => Maybe v -> NumError -> EnsureCN v
diff --git a/src/Numeric/MixedTypes/AddSub.hs b/src/Numeric/MixedTypes/AddSub.hs
--- a/src/Numeric/MixedTypes/AddSub.hs
+++ b/src/Numeric/MixedTypes/AddSub.hs
@@ -17,12 +17,12 @@
     CanAdd, CanAddAsymmetric(..), CanAddThis, CanAddSameType
     , (+), sum
   -- ** Tests
-    , specCanAdd, specCanAddNotMixed, specCanAddSameType, CanAddX, CanAddXX,
+    , specCanAdd, specCanAddNotMixed, specCanAddSameType
     -- * Subtraction
-    CanSub(..), CanSubThis, CanSubSameType
+    , CanSub(..), CanSubThis, CanSubSameType
     , (-)
   -- ** Tests
-    , specCanSub, specCanSubNotMixed, CanSubX
+    , specCanSub, specCanSubNotMixed
 )
 where
 
@@ -41,7 +41,7 @@
 import Control.CollectErrors
 
 import Numeric.MixedTypes.Literals
-import Numeric.MixedTypes.Bool (CanNeg(..))
+import Numeric.MixedTypes.Bool
 import Numeric.MixedTypes.Eq
 import Numeric.MixedTypes.Ord
 import Numeric.MixedTypes.MinMaxAbs ()
@@ -60,7 +60,7 @@
   type AddType t1 t2
   type AddType t1 t2 = t1 -- default
   add :: t1 -> t2 -> AddType t1 t2
-  default add :: (AddType t1 t2 ~ t1, t1~t2, P.Num t1) => t1 -> t1 -> t1
+  default add :: (AddType t1 t2 ~ t1, t1~t2, P.Num t1) => t1 -> t2 -> AddType t1 t2
   add = (P.+)
 
 infixl 6  +, -
@@ -79,36 +79,32 @@
 sum :: (CanAddSameType t, ConvertibleExactly Integer t) => [t] -> t
 sum xs = List.foldl' add (convertExactly 0) xs
 
-{-| Compound type constraint useful for test definition. -}
-type CanAddX t1 t2 =
-  (CanAdd t1 t2,
-   Show t1, Arbitrary t1,
-   Show t2, Arbitrary t2,
-   Show (AddType t1 t2),
-   HasEqCertainly t1 (AddType t1 t2),
-   HasEqCertainly t2 (AddType t1 t2),
-   HasEqCertainly (AddType t1 t2) (AddType t1 t2),
-   HasOrderCertainly t1 (AddType t1 t2),
-   HasOrderCertainly t2 (AddType t1 t2),
-   HasOrderCertainly (AddType t1 t2) (AddType t1 t2))
-
-{-| Compound type constraint useful for test definition. -}
-type CanAddXX t1 t2 =
-  (CanAddX t1 t2,
-   HasEqCertainly (AddType t1 t2) (AddType t2 t1))
-
 {-|
   HSpec properties that each implementation of CanAdd should satisfy.
  -}
 specCanAdd ::
-  (CanAddXX t1 t1,
-   CanAddXX t1 t2,
-   CanAddXX t1 t3, CanAddXX t2 t3,
-   CanAddXX t1 (AddType t2 t3),
-   CanAddXX (AddType t1 t2) t3,
-   ConvertibleExactly Integer t1,
-   CanTestPosNeg t1,
-   HasEqCertainly (AddType t1 (AddType t2 t3)) (AddType (AddType t1 t2) t3))
+  (Show t1, Show t2, Show t3, Show (AddType t1 t1),
+   Show (AddType t1 t2), Show (AddType t2 t1),
+   Show (AddType t1 (AddType t2 t3)),
+   Show (AddType (AddType t1 t2) t3), Arbitrary t1, Arbitrary t2,
+   Arbitrary t3, ConvertibleExactly Integer t1,
+   CanTestCertainly
+     (EqCompareType (AddType t1 t1) t1),
+   CanTestCertainly
+     (EqCompareType (AddType t1 t2) (AddType t2 t1)),
+   CanTestCertainly
+     (EqCompareType
+        (AddType t1 (AddType t2 t3)) (AddType (AddType t1 t2) t3)),
+   CanTestCertainly
+     (OrderCompareType (AddType t1 t2) t2),
+   HasEqAsymmetric (AddType t1 t1) t1,
+   HasEqAsymmetric (AddType t1 t2) (AddType t2 t1),
+   HasEqAsymmetric
+     (AddType t1 (AddType t2 t3)) (AddType (AddType t1 t2) t3),
+   HasOrderAsymmetric (AddType t1 t2) t2, CanTestPosNeg t1,
+   CanAddAsymmetric t1 t1, CanAddAsymmetric t1 t2,
+   CanAddAsymmetric t1 (AddType t2 t3), CanAddAsymmetric t2 t1,
+   CanAddAsymmetric t2 t3, CanAddAsymmetric (AddType t1 t2) t3)
   =>
   T t1 -> T t2 -> T t3 -> Spec
 specCanAdd (T typeName1 :: T t1) (T typeName2 :: T t2) (T typeName3 :: T t3) =
@@ -139,13 +135,25 @@
   HSpec properties that each implementation of CanAdd should satisfy.
  -}
 specCanAddNotMixed ::
-  (CanAddXX t t,
-   CanAddXX t (AddType t t),
+  (Show t, Show (AddType t t), Show (AddType t (AddType t t)),
+   Show (AddType (AddType t t) t), Arbitrary t,
    ConvertibleExactly Integer t,
-   CanTestPosNeg t)
+   CanTestCertainly (EqCompareType (AddType t t) t),
+   CanTestCertainly (EqCompareType (AddType t t) (AddType t t)),
+   CanTestCertainly
+     (EqCompareType
+        (AddType t (AddType t t)) (AddType (AddType t t) t)),
+   CanTestCertainly (OrderCompareType (AddType t t) t),
+   HasEqAsymmetric (AddType t t) t,
+   HasEqAsymmetric (AddType t t) (AddType t t),
+   HasEqAsymmetric
+     (AddType t (AddType t t)) (AddType (AddType t t) t),
+   HasOrderAsymmetric (AddType t t) t, CanTestPosNeg t,
+   CanAddAsymmetric t t, CanAddAsymmetric t (AddType t t),
+   CanAddAsymmetric (AddType t t) t)
   =>
   T t -> Spec
-specCanAddNotMixed t = specCanAdd t t t
+specCanAddNotMixed (t :: T t) = specCanAdd t t t
 
 {-|
   HSpec properties that each implementation of CanAddSameType should satisfy.
@@ -228,7 +236,8 @@
 
 instance
   (CanAddAsymmetric a b
-  , CanEnsureCE es   (AddType a b)
+  , CanEnsureCE es a, CanEnsureCE es b
+  , CanEnsureCE es (AddType a b)
   , SuitableForCE es)
   =>
   CanAddAsymmetric (CollectErrors es a) (CollectErrors es  b)
@@ -264,24 +273,19 @@
 type CanSubSameType t =
   CanSubThis t t
 
-{-| Compound type constraint useful for test definition. -}
-type CanSubX t1 t2 =
-  (CanSub t1 t2,
-   HasEqCertainly t1 (SubType t1 t2),
-   CanAddXX t1 t2,
-   Show (SubType t1 t2))
-
 {-|
   HSpec properties that each implementation of CanSub should satisfy.
  -}
 specCanSub ::
-  (CanSubX t1 t1,
-   CanSubX t1 t2,
-   CanNeg t2,
-   CanAdd t1 (NegType t2),
-   HasEqCertainly (SubType t1 t2) (AddType t1 (NegType t2)),
-   Show (AddType t1 (NegType t2)),
-   ConvertibleExactly Integer t1)
+  (Show t1, Show t2, Show (SubType t1 t1), Show (SubType t1 t2),
+   Show (AddType t1 (NegType t2)), Arbitrary t1, Arbitrary t2,
+   ConvertibleExactly Integer t1,
+   CanTestCertainly (EqCompareType (SubType t1 t1) t1),
+   CanTestCertainly
+     (EqCompareType (SubType t1 t2) (AddType t1 (NegType t2))),
+   CanNeg t2, HasEqAsymmetric (SubType t1 t1) t1,
+   HasEqAsymmetric (SubType t1 t2) (AddType t1 (NegType t2)),
+   CanSub t1 t1, CanSub t1 t2, CanAddAsymmetric t1 (NegType t2))
   =>
   T t1 -> T t2 -> Spec
 specCanSub (T typeName1 :: T t1) (T typeName2 :: T t2) =
@@ -302,16 +306,17 @@
   HSpec properties that each implementation of CanSub should satisfy.
  -}
 specCanSubNotMixed ::
-  (CanSubX t t,
-   CanSubX t (SubType t t),
-   CanNeg t,
-   CanAdd t (NegType t),
-   Show (AddType t (NegType t)),
-   HasEqCertainly (SubType t t) (AddType t (NegType t)),
-   ConvertibleExactly Integer t)
+  (Show t, Show (SubType t t), Show (AddType t (NegType t)),
+   Arbitrary t, ConvertibleExactly Integer t,
+   CanTestCertainly (EqCompareType (SubType t t) t),
+   CanTestCertainly
+     (EqCompareType (SubType t t) (AddType t (NegType t))),
+   CanNeg t, HasEqAsymmetric (SubType t t) t,
+   HasEqAsymmetric (SubType t t) (AddType t (NegType t)), CanSub t t,
+   CanAddAsymmetric t (NegType t))
   =>
   T t -> Spec
-specCanSubNotMixed t = specCanSub t t
+specCanSubNotMixed (t :: T t) = specCanSub t t
 
 instance CanSub Int Int where
   type SubType Int Int = Integer -- do not risk overflow
@@ -376,6 +381,7 @@
 
 instance
   (CanSub a b
+  , CanEnsureCE es a, CanEnsureCE es b
   , CanEnsureCE es (SubType a b)
   , SuitableForCE es)
   =>
@@ -385,13 +391,13 @@
     EnsureCE es (SubType a b)
   sub = lift2CE sub
 
-
 $(declForTypes
   [[t| Integer |], [t| Int |], [t| Rational |], [t| Double |]]
   (\ t -> [d|
 
     instance
       (CanSub $t b
+      , CanEnsureCE es b
       , CanEnsureCE es (SubType $t b)
       , SuitableForCE es)
       =>
@@ -403,6 +409,7 @@
 
     instance
       (CanSub a $t
+      , CanEnsureCE es a
       , CanEnsureCE es (SubType a $t)
       , SuitableForCE es)
       =>
@@ -414,6 +421,7 @@
 
     instance
       (CanAddAsymmetric $t b
+      , CanEnsureCE es b
       , CanEnsureCE es (AddType $t b)
       , SuitableForCE es)
       =>
@@ -425,6 +433,7 @@
 
     instance
       (CanAddAsymmetric a $t
+      , CanEnsureCE es a
       , CanEnsureCE es (AddType a $t)
       , SuitableForCE es)
       =>
diff --git a/src/Numeric/MixedTypes/Bool.hs b/src/Numeric/MixedTypes/Bool.hs
--- a/src/Numeric/MixedTypes/Bool.hs
+++ b/src/Numeric/MixedTypes/Bool.hs
@@ -21,11 +21,11 @@
   -- * Negation
   , CanNeg(..), not, CanNegSameType
   -- ** Tests
-  , specCanNegBool, CanNegBoolX
+  , specCanNegBool
   -- * And and or
   , CanAndOr, CanAndOrAsymmetric(..), (&&), (||), CanAndOrWith, CanAndOrSameType, and, or
   -- ** Tests
-  , specCanAndOr, specCanAndOrNotMixed, CanAndOrX
+  , specCanAndOr, specCanAndOrNotMixed
 )
 where
 
@@ -153,15 +153,14 @@
 {-| Compound type constraint useful for test definition. -}
 type CanTestCertainlyX t = (CanTestCertainly t, Show t, SCS.Serial IO t)
 
-{-| Compound type constraint useful for test definition. -}
-type CanNegBoolX t =
-  (CanNeg t, CanTestCertainlyX t, CanTestCertainlyX (NegType t))
-
 {-|
   HSpec properties that each Boolean implementation of CanNeg should satisfy.
  -}
 specCanNegBool ::
-  (CanNegBoolX t, CanNegBoolX (NegType t))
+  (Show t, Show (NegType (NegType t)), SCS.Serial IO t,
+   CanTestCertainly t, CanTestCertainly (NegType t),
+   CanTestCertainly (NegType (NegType t)), CanNeg t,
+   CanNeg (NegType t))
   =>
   T t -> Spec
 specCanNegBool (T typeName :: T t) =
@@ -186,7 +185,7 @@
 _testNeg1 = not (Just True)
 
 instance
-  (CanNeg t, SuitableForCE es, CanEnsureCE es (NegType t))
+  (CanNeg t, SuitableForCE es, CanEnsureCE es t, CanEnsureCE es (NegType t))
   =>
   CanNeg (CollectErrors es t) where
   type NegType (CollectErrors es t) = EnsureCE es (NegType t)
@@ -230,32 +229,32 @@
 or :: (CanAndOrSameType t, CanTestCertainly t) => [t] -> t
 or = List.foldl' (||) (convertExactly False)
 
-{-| Compound type constraint useful for test definition. -}
-type CanAndOrX t1 t2 =
-  (CanAndOr t1 t2,
-   CanNeg t1,
-   CanNeg t2,
-   CanAndOr (NegType t1) t2,
-   CanAndOr t1 (NegType t2),
-   CanAndOr (NegType t1) (NegType t2),
-   CanTestCertainlyX t1,
-   CanTestCertainlyX t2,
-   CanTestCertainlyX (AndOrType t1 t2),
-   CanTestCertainlyX (NegType (AndOrType t1 t2)),
-   CanTestCertainlyX (AndOrType (NegType t1) t2),
-   CanTestCertainlyX (AndOrType t1 (NegType t2)),
-   CanTestCertainlyX (AndOrType (NegType t1) (NegType t2))
-   )
-
 {-|
   HSpec properties that each implementation of CanAndOr should satisfy.
  -}
 specCanAndOr ::
-  (CanAndOrX t1 t1,
-   CanAndOrX t1 t2, CanAndOrX t2 t1,
-   CanAndOrX t1 t3, CanAndOrX t2 t3,
-   CanAndOrX (AndOrType t1 t2) t3, CanAndOrX t1 (AndOrType t2 t3),
-   CanAndOrX (AndOrType t1 t2) (AndOrType t1 t3))
+  (Show t1, Show t2, Show t3, Show (AndOrType t1 t1),
+   Show (AndOrType t1 t2), Show (AndOrType t2 t1),
+   Show (AndOrType t1 (AndOrType t2 t3)),
+   Show (AndOrType (AndOrType t1 t2) t3),
+   Show (AndOrType (AndOrType t1 t2) (AndOrType t1 t3)),
+   Show (NegType (AndOrType t1 t2)),
+   Show (AndOrType (NegType t1) (NegType t2)), SCS.Serial IO t1,
+   SCS.Serial IO t2, SCS.Serial IO t3, CanTestCertainly t1,
+   CanTestCertainly (AndOrType t1 t1),
+   CanTestCertainly (AndOrType t1 t2),
+   CanTestCertainly (AndOrType t2 t1),
+   CanTestCertainly (AndOrType t1 (AndOrType t2 t3)),
+   CanTestCertainly (AndOrType (AndOrType t1 t2) t3),
+   CanTestCertainly (AndOrType (AndOrType t1 t2) (AndOrType t1 t3)),
+   CanTestCertainly (NegType (AndOrType t1 t2)),
+   CanTestCertainly (AndOrType (NegType t1) (NegType t2)), CanNeg t1,
+   CanNeg t2, CanNeg (AndOrType t1 t2), CanAndOrAsymmetric t1 t1,
+   CanAndOrAsymmetric t1 t2, CanAndOrAsymmetric t1 t3,
+   CanAndOrAsymmetric t1 (AndOrType t2 t3), CanAndOrAsymmetric t2 t1,
+   CanAndOrAsymmetric t2 t3, CanAndOrAsymmetric (AndOrType t1 t2) t3,
+   CanAndOrAsymmetric (AndOrType t1 t2) (AndOrType t1 t3),
+   CanAndOrAsymmetric (NegType t1) (NegType t2))
   =>
   T t1 -> T t2 -> T t3 -> Spec
 specCanAndOr (T typeName1 ::T t1) (T typeName2 :: T t2) (T typeName3 :: T t3) =
@@ -289,9 +288,23 @@
   HSpec properties that each implementation of CanAndOr should satisfy.
  -}
 specCanAndOrNotMixed ::
-  (CanAndOrX t t,
-   CanAndOrX (AndOrType t t) t, CanAndOrX t (AndOrType t t),
-   CanAndOrX (AndOrType t t) (AndOrType t t))
+  (Show t, Show (AndOrType t t),
+   Show (AndOrType t (AndOrType t t)),
+   Show (AndOrType (AndOrType t t) t),
+   Show (AndOrType (AndOrType t t) (AndOrType t t)),
+   Show (NegType (AndOrType t t)),
+   Show (AndOrType (NegType t) (NegType t)), SCS.Serial IO t,
+   CanTestCertainly t, CanTestCertainly (AndOrType t t),
+   CanTestCertainly (AndOrType t (AndOrType t t)),
+   CanTestCertainly (AndOrType (AndOrType t t) t),
+   CanTestCertainly (AndOrType (AndOrType t t) (AndOrType t t)),
+   CanTestCertainly (NegType (AndOrType t t)),
+   CanTestCertainly (AndOrType (NegType t) (NegType t)), CanNeg t,
+   CanNeg (AndOrType t t), CanAndOrAsymmetric t t,
+   CanAndOrAsymmetric t (AndOrType t t),
+   CanAndOrAsymmetric (AndOrType t t) t,
+   CanAndOrAsymmetric (AndOrType t t) (AndOrType t t),
+   CanAndOrAsymmetric (NegType t) (NegType t))
   =>
   T t -> Spec
 specCanAndOrNotMixed t = specCanAndOr t t t
@@ -349,21 +362,30 @@
 _testAndOr3 :: Maybe Bool
 _testAndOr3 = and [Just True, Nothing, Just False]
 
-instance (CanAndOrAsymmetric t1 t2, SuitableForCE es, CanEnsureCE es (AndOrType t1 t2)) =>
+instance
+  (CanAndOrAsymmetric t1 t2, SuitableForCE es
+  , CanEnsureCE es t1, CanEnsureCE es t2, CanEnsureCE es (AndOrType t1 t2))
+  =>
   CanAndOrAsymmetric (CollectErrors es t1) (CollectErrors es t2)
   where
   type AndOrType (CollectErrors es t1) (CollectErrors es t2) = EnsureCE es (AndOrType t1 t2)
   and2 = lift2CE and2
   or2 = lift2CE or2
 
-instance (CanAndOrAsymmetric t1 Bool, SuitableForCE es, CanEnsureCE es (AndOrType t1 Bool)) =>
+instance
+  (CanAndOrAsymmetric t1 Bool, SuitableForCE es
+  , CanEnsureCE es t1, CanEnsureCE es (AndOrType t1 Bool))
+  =>
   CanAndOrAsymmetric (CollectErrors es t1) Bool
   where
   type AndOrType (CollectErrors es t1) Bool = EnsureCE es (AndOrType t1 Bool)
   and2 = lift2TCE and2
   or2 = lift2TCE or2
 
-instance (CanAndOrAsymmetric Bool t2, SuitableForCE es, CanEnsureCE es (AndOrType Bool t2)) =>
+instance
+  (CanAndOrAsymmetric Bool t2, SuitableForCE es
+  , CanEnsureCE es t2, CanEnsureCE es (AndOrType Bool t2))
+  =>
   CanAndOrAsymmetric Bool (CollectErrors es t2)
   where
   type AndOrType Bool (CollectErrors es t2) = EnsureCE es (AndOrType Bool t2)
diff --git a/src/Numeric/MixedTypes/Elementary.hs b/src/Numeric/MixedTypes/Elementary.hs
--- a/src/Numeric/MixedTypes/Elementary.hs
+++ b/src/Numeric/MixedTypes/Elementary.hs
@@ -56,26 +56,23 @@
   type SqrtType t
   type SqrtType t = t -- default
   sqrt :: t -> SqrtType t
-  default sqrt :: (SqrtType t ~ t, P.Floating t) => t -> t
+  default sqrt :: (SqrtType t ~ t, P.Floating t) => t -> SqrtType t
   sqrt = P.sqrt
 
 type CanSqrtSameType t = (CanSqrt t, SqrtType t ~ t)
 type CanSqrtCNSameType t = (CanSqrt t, SqrtType t ~ EnsureCN t)
 
-type CanSqrtX t =
-  (CanSqrt t,
-   CanTestPosNeg t,
-   HasEqCertainly t (SqrtType t),
-   HasOrderCertainly Integer (SqrtType t),
-   Show t, Arbitrary t, Show (SqrtType t))
-
 {-|
   HSpec properties that each implementation of CanSqrt should satisfy.
  -}
 specCanSqrtReal ::
-  (CanSqrtX t,
-   CanPowX (SqrtType t) Integer,
-   HasEqCertainly t (PowType (SqrtType t) Integer))
+  (Show t, Show (SqrtType t), Show (PowType (SqrtType t) Integer),
+    Arbitrary t,
+    CanTestCertainly (OrderCompareType (SqrtType t) Integer),
+    CanTestCertainly (EqCompareType (PowType (SqrtType t) Integer) t),
+    HasEqAsymmetric (PowType (SqrtType t) Integer) t,
+    HasOrderAsymmetric (SqrtType t) Integer, CanTestPosNeg t,
+    CanPow (SqrtType t) Integer, CanSqrt t)
   =>
   T t -> Spec
 specCanSqrtReal (T typeName :: T t) =
@@ -105,6 +102,7 @@
 
 instance
   (CanSqrt a
+  , CanEnsureCE es a
   , CanEnsureCE es (SqrtType a)
   , SuitableForCE es)
   =>
@@ -124,30 +122,41 @@
   type ExpType t
   type ExpType t = t -- default
   exp :: t -> ExpType t
-  default exp :: (ExpType t ~ t, P.Floating t) => t -> t
+  default exp :: (ExpType t ~ t, P.Floating t) => t -> ExpType t
   exp = P.exp
 
 type CanExpSameType t = (CanExp t, ExpType t ~ t)
 
-type CanExpX t =
-  (CanExp t,
-   Ring t,
-   Field (ExpType t),
-   CanTestPosNeg t,
-   CanTestPosNeg (ExpType t),
-   HasEqCertainlyCN (ExpType t) (ExpType t),
-   HasOrderCertainly Integer t,
-   HasOrderCertainly Integer (ExpType t),
-   Show t, Arbitrary t, Show (ExpType t),
-   Show (EnsureCN t), Show (EnsureCN (ExpType t)))
-
 {-|
   HSpec properties that each implementation of CanExp should satisfy.
  -}
 specCanExpReal ::
-  (CanExpX t)
-  =>
-  T t -> Spec
+  (Show t, Show (ExpType t), Show (DivType Integer (ExpType t)),
+   Show (ExpType (AddType t t)),
+   Show (MulType (ExpType t) (ExpType t)),
+   Show (EnsureCN (ExpType t)), Arbitrary t,
+   CanEnsureCN (ExpType t),
+   CanTestCertainly (OrderCompareType Integer t),
+   CanTestCertainly (OrderCompareType t Integer),
+   CanTestCertainly (OrderCompareType (ExpType t) Integer),
+   CanTestCertainly
+     (EqCompareType
+        (EnsureCN (ExpType t)) (DivType Integer (ExpType t))),
+   CanTestCertainly
+     (EqCompareType
+        (ExpType (AddType t t)) (MulType (ExpType t) (ExpType t))),
+   CanNeg t,
+   HasEqAsymmetric
+     (ExpType (AddType t t)) (MulType (ExpType t) (ExpType t)),
+   HasEqAsymmetric
+     (EnsureCN (ExpType t)) (DivType Integer (ExpType t)),
+   HasOrderAsymmetric t Integer,
+   HasOrderAsymmetric (ExpType t) Integer,
+   HasOrderAsymmetric Integer t, CanAddAsymmetric t t,
+   CanMulAsymmetric (ExpType t) (ExpType t),
+   CanDiv Integer (ExpType t), CanExp t, CanExp (AddType t t),
+   NegType t ~ t) =>
+   T t -> Spec
 specCanExpReal (T typeName :: T t) =
   describe (printf "CanExp %s" typeName) $ do
     it "exp(x) >= 0" $ do
@@ -180,6 +189,7 @@
 
 instance
   (CanExp a
+  , CanEnsureCE es a
   , CanEnsureCE es (ExpType a)
   , SuitableForCE es)
   =>
@@ -198,31 +208,42 @@
   type LogType t
   type LogType t = t -- default
   log :: t -> LogType t
-  default log :: (LogType t ~ t, P.Floating t) => t -> t
+  default log :: (LogType t ~ t, P.Floating t) => t -> LogType t
   log = P.log
 
 type CanLogSameType t = (CanLog t, LogType t ~ t)
 type CanLogCNSameType t = (CanLog t, LogType t ~ EnsureCN t)
 
-type CanLogX t =
-  (CanLog t,
-   Field t,
-   Ring (LogType t),
-   HasOrderCertainly t Integer,
-   HasOrderCertainlyCN t Integer,
-   HasEqCertainly (LogType t) (LogType t),
-   Show t, Arbitrary t, Show (LogType t))
-
 {-|
   HSpec properties that each implementation of CanLog should satisfy.
  -}
 specCanLogReal ::
-  (CanLogX t,
-   CanLogX (DivType Integer t),
-   CanExp t, CanLogX (ExpType t),
-   HasEqCertainly (LogType t) (LogType (EnsureCN t)),
-   HasEqCertainlyCN t (LogType (ExpType t)))
-  =>
+  (Show t, Show (LogType t), Show (LogType (DivType Integer t)),
+   Show (LogType (MulType t t)),
+   Show (AddType (LogType t) (LogType t)), Show (LogType (ExpType t)),
+   Arbitrary t, CanTestCertainly (OrderCompareType t Integer),
+   CanTestCertainly (OrderCompareType (DivType Integer t) Integer),
+   CanTestCertainly
+     (EqCompareType (LogType (DivType Integer t)) (LogType t)),
+   CanTestCertainly (OrderCompareType (MulType t t) Integer),
+   CanTestCertainly
+     (EqCompareType
+        (LogType (MulType t t)) (AddType (LogType t) (LogType t))),
+   CanTestCertainly (OrderCompareType Integer t),
+   CanTestCertainly (EqCompareType (LogType (ExpType t)) t),
+   CanNeg (LogType t),
+   HasEqAsymmetric (LogType (DivType Integer t)) (LogType t),
+   HasEqAsymmetric
+     (LogType (MulType t t)) (AddType (LogType t) (LogType t)),
+   HasEqAsymmetric (LogType (ExpType t)) t,
+   HasOrderAsymmetric t Integer,
+   HasOrderAsymmetric (DivType Integer t) Integer,
+   HasOrderAsymmetric (MulType t t) Integer,
+   HasOrderAsymmetric Integer t,
+   CanAddAsymmetric (LogType t) (LogType t), CanMulAsymmetric t t,
+   CanDiv Integer t, CanExp t, CanLog t, CanLog (DivType Integer t),
+   CanLog (MulType t t), CanLog (ExpType t),
+   LogType t ~ NegType (LogType t)) =>
   T t -> Spec
 specCanLogReal (T typeName :: T t) =
   describe (printf "CanLog %s" typeName) $ do
@@ -252,6 +273,7 @@
 
 instance
   (CanLog a
+  , CanEnsureCE es a
   , CanEnsureCE es (LogType a)
   , SuitableForCE es)
   =>
@@ -261,18 +283,26 @@
   log = lift1CE log
 
 instance CanPow Double Double where
+  powNoCN = (P.**)
+  type PowType Double Double = Double
   pow = (P.**)
-  -- pow = powUsingExpLog
 instance CanPow Double Rational where
+  powNoCN b e = b ^! (double e)
   type PowType Double Rational = Double
   pow b e = b ^ (double e)
 instance CanPow Rational Double where
+  type PowTypeNoCN Rational Double = Double
+  powNoCN b e = (double b) ^! e
   type PowType Rational Double = Double
   pow b e = (double b) ^ e
 instance CanPow Integer Double where
+  type PowTypeNoCN Integer Double = Double
+  powNoCN b e = (double b) ^! e
   type PowType Integer Double = Double
   pow b e = (double b) ^ e
 instance CanPow Int Double where
+  type PowTypeNoCN Int Double = Double
+  powNoCN b e = (double b) ^! e
   type PowType Int Double = Double
   pow b e = (double b) ^ e
 
@@ -286,18 +316,16 @@
    CanMulSameType (EnsureCN t),
    CanExpSameType (EnsureCN t),
    CanTestInteger t,
-   HasIntegers t,
    CanTestZero t,
-   CanRecipCNSameType t,
-   HasIntegers (EnsureCN t))
+   CanRecipCNSameType t)
   =>
-  t -> t -> EnsureCN t
-powUsingExpLog b e =
+  t -> t -> t -> t -> EnsureCN t
+powUsingExpLog zero one b e =
   case certainlyIntegerGetIt e of
     Just n ->
-      powUsingMulRecip b n
+      powUsingMulRecip one b n
     Nothing
-      | isCertainlyZero b && isCertainlyPositive e -> convertExactly 0
+      | isCertainlyZero b && isCertainlyPositive e -> cn zero
       | isCertainlyNonNegative b -> exp ((log b) * (ensureCN e))
       | isCertainlyNegative b && certainlyNotInteger e -> noValueNumErrorCertainECN (Just b) err
       | otherwise -> noValueNumErrorPotentialECN (Just b) err
@@ -314,22 +342,14 @@
   type SinCosType t
   type SinCosType t = t -- default
   cos :: t -> SinCosType t
-  default cos :: (SinCosType t ~ t, P.Floating t) => t -> t
+  default cos :: (SinCosType t ~ t, P.Floating t) => t -> SinCosType t
   cos = P.cos
   sin :: t -> SinCosType t
-  default sin :: (SinCosType t ~ t, P.Floating t) => t -> t
+  default sin :: (SinCosType t ~ t, P.Floating t) => t -> SinCosType t
   sin = P.sin
 
 type CanSinCosSameType t = (CanSinCos t, SinCosType t ~ t)
 
-type CanSinCosX t =
-  (CanSinCos t,
-   OrderedCertainlyField t,
-   OrderedCertainlyField (SinCosType t),
-   HasOrderCertainlyCN (SinCosType t) t,
-   Show t, Arbitrary t, Show (SinCosType t),
-   Show (EnsureCN t), Arbitrary t, Show (EnsureCN (SinCosType t)))
-
 {-|
   HSpec properties that each implementation of CanSinCos should satisfy.
 
@@ -337,7 +357,79 @@
   http://math.stackexchange.com/questions/1303044/axiomatic-definition-of-sin-and-cos
  -}
 specCanSinCosReal ::
-  (CanSinCosX t)
+ (Show t, Show (SinCosType t),
+  Show
+    (AddType
+       (PowType (SinCosType t) Integer) (PowType (SinCosType t) Integer)),
+  Show (SinCosType (SubType t t)),
+  Show
+    (SubType
+       (MulType (SinCosType t) (SinCosType t))
+       (MulType (SinCosType t) (SinCosType t))),
+  Show
+    (AddType
+       (MulType (SinCosType t) (SinCosType t))
+       (MulType (SinCosType t) (SinCosType t))),
+  Show (DivType (SinCosType t) (SinCosType t)),
+  Show (EnsureCN t), Arbitrary t, CanEnsureCN t,
+  CanTestCertainly (OrderCompareType Integer (SinCosType t)),
+  CanTestCertainly (OrderCompareType (SinCosType t) Integer),
+  CanTestCertainly
+    (EqCompareType
+       (AddType
+          (PowType (SinCosType t) Integer)
+          (PowType (SinCosType t) Integer))
+       Integer),
+  CanTestCertainly
+    (EqCompareType
+       (SinCosType (SubType t t))
+       (SubType
+          (MulType (SinCosType t) (SinCosType t))
+          (MulType (SinCosType t) (SinCosType t)))),
+  CanTestCertainly
+    (EqCompareType
+       (SinCosType (SubType t t))
+       (AddType
+          (MulType (SinCosType t) (SinCosType t))
+          (MulType (SinCosType t) (SinCosType t)))),
+  CanTestCertainly (OrderCompareType t Integer),
+  CanTestCertainly (OrderCompareType t Rational),
+  CanTestCertainly (OrderCompareType (SinCosType t) t),
+  CanTestCertainly
+    (OrderCompareType
+       (EnsureCN t) (DivType (SinCosType t) (SinCosType t))),
+  HasEqAsymmetric
+    (AddType
+       (PowType (SinCosType t) Integer) (PowType (SinCosType t) Integer))
+    Integer,
+  HasEqAsymmetric
+    (SinCosType (SubType t t))
+    (SubType
+       (MulType (SinCosType t) (SinCosType t))
+       (MulType (SinCosType t) (SinCosType t))),
+  HasEqAsymmetric
+    (SinCosType (SubType t t))
+    (AddType
+       (MulType (SinCosType t) (SinCosType t))
+       (MulType (SinCosType t) (SinCosType t))),
+  HasOrderAsymmetric t Integer, HasOrderAsymmetric t Rational,
+  HasOrderAsymmetric (SinCosType t) t,
+  HasOrderAsymmetric (SinCosType t) Integer,
+  HasOrderAsymmetric
+    (EnsureCN t) (DivType (SinCosType t) (SinCosType t)),
+  HasOrderAsymmetric Integer (SinCosType t), CanSub t t,
+  CanSub
+    (MulType (SinCosType t) (SinCosType t))
+    (MulType (SinCosType t) (SinCosType t)),
+  CanAddAsymmetric
+    (PowType (SinCosType t) Integer) (PowType (SinCosType t) Integer),
+  CanAddAsymmetric
+    (MulType (SinCosType t) (SinCosType t))
+    (MulType (SinCosType t) (SinCosType t)),
+  CanPow (SinCosType t) Integer,
+  CanMulAsymmetric (SinCosType t) (SinCosType t),
+  CanDiv (SinCosType t) (SinCosType t), CanSinCos t,
+  CanSinCos (SubType t t))
   =>
   T t -> Spec
 specCanSinCosReal (T typeName :: T t) =
@@ -378,6 +470,7 @@
 
 instance
   (CanSinCos a
+  , CanEnsureCE es a
   , CanEnsureCE es (SinCosType a)
   , SuitableForCE es)
   =>
diff --git a/src/Numeric/MixedTypes/Eq.hs b/src/Numeric/MixedTypes/Eq.hs
--- a/src/Numeric/MixedTypes/Eq.hs
+++ b/src/Numeric/MixedTypes/Eq.hs
@@ -19,7 +19,7 @@
   , notCertainlyDifferentFrom, certainlyEqualTo, certainlyNotEqualTo
   , (?==?), (!==!), (!/=!)
   -- ** Tests
-  , specHasEq, specHasEqNotMixed, HasEqX
+  , specHasEq, specHasEqNotMixed
   , specConversion
   -- ** Specific comparisons
   , CanTestNaN(..)
@@ -80,7 +80,7 @@
     type EqCompareType a b = Bool -- default
     equalTo :: a -> b -> (EqCompareType a b)
     -- default equalToA via Prelude for (->) and Bool:
-    default equalTo :: (EqCompareType a b ~ Bool, a~b, P.Eq a) => a -> b -> Bool
+    default equalTo :: (EqCompareType a b ~ Bool, a~b, P.Eq a) => a -> b -> EqCompareType a b
     equalTo = (P.==)
     notEqualTo :: a -> b -> (EqCompareType a b)
     -- default notEqualToA via equalToA for Bool:
@@ -110,18 +110,20 @@
 (!/=!) :: (HasEqCertainlyAsymmetric a b) => a -> b -> Bool
 (!/=!) = certainlyNotEqualTo
 
-{-| Compound type constraint useful for test definition. -}
-type HasEqX t1 t2 =
-  (HasEqCertainly t1 t2, Show t1, Arbitrary t1, Show t2, Arbitrary t2)
-
 {-|
   HSpec properties that each implementation of HasEq should satisfy.
  -}
 specHasEq ::
-  (HasEqX t1 t1,
-   HasEqX t1 t2, HasEqX t2 t1,
-   HasEqX t1 t3, HasEqX t2 t3,
-   CanAndOrX (EqCompareType t1 t2) (EqCompareType t2 t3))
+ (Show t1, Show t2, Show t3, Arbitrary t1, Arbitrary t2,
+  Arbitrary t3, CanTestCertainly (EqCompareType t1 t1),
+  CanTestCertainly (EqCompareType t1 t2),
+  CanTestCertainly (EqCompareType t2 t1),
+  CanTestCertainly (EqCompareType t2 t3),
+  CanTestCertainly
+    (AndOrType (EqCompareType t1 t2) (EqCompareType t2 t3)),
+  CanAndOrAsymmetric (EqCompareType t1 t2) (EqCompareType t2 t3),
+  HasEqAsymmetric t1 t1, HasEqAsymmetric t1 t2,
+  HasEqAsymmetric t2 t1, HasEqAsymmetric t2 t3)
   =>
   T t1 -> T t2 -> T t3 -> Spec
 specHasEq (T typeName1 :: T t1) (T typeName2 :: T t2) (T typeName3 :: T t3) =
@@ -141,11 +143,13 @@
   HSpec properties that each implementation of HasEq should satisfy.
  -}
 specHasEqNotMixed ::
-  (HasEqX t t,
-   CanAndOrX (EqCompareType t t) (EqCompareType t t))
+  (Show t, Arbitrary t, CanTestCertainly (EqCompareType t t),
+   CanTestCertainly
+     (AndOrType (EqCompareType t t) (EqCompareType t t)),
+   HasEqAsymmetric t t)
   =>
   T t -> Spec
-specHasEqNotMixed t = specHasEq t t t
+specHasEqNotMixed (t :: T t) = specHasEq t t t
 
 {-|
   HSpec property of there-and-back conversion.
@@ -247,6 +251,7 @@
 instance
   (HasEqAsymmetric a b
   , CanEnsureCE es (EqCompareType a b)
+  , CanEnsureCE es a, CanEnsureCE es b
   , IsBool (EnsureCE es (EqCompareType a b))
   , SuitableForCE es)
   =>
@@ -262,6 +267,7 @@
 
     instance
       (HasEqAsymmetric $t b
+      , CanEnsureCE es b
       , CanEnsureCE es (EqCompareType $t b)
       , IsBool (EnsureCE es (EqCompareType $t b))
       , SuitableForCE es)
@@ -274,6 +280,7 @@
 
     instance
       (HasEqAsymmetric a $t
+      , CanEnsureCE es a
       , CanEnsureCE es (EqCompareType a $t)
       , IsBool (EnsureCE es (EqCompareType a $t))
       , SuitableForCE es)
diff --git a/src/Numeric/MixedTypes/Field.hs b/src/Numeric/MixedTypes/Field.hs
--- a/src/Numeric/MixedTypes/Field.hs
+++ b/src/Numeric/MixedTypes/Field.hs
@@ -14,14 +14,14 @@
 module Numeric.MixedTypes.Field
 (
   -- * Field
-  CanAddSubMulDivCNBy, Field, CertainlyEqField, OrderedField, OrderedCertainlyField
+  CanAddSubMulDivCNBy, Field, OrderedField, OrderedCertainlyField
   -- * Division
   , CanDiv(..), CanDivBy, CanDivCNBy, CanDivSameType, CanDivCNSameType
   , CanRecip, CanRecipSameType, CanRecipCNSameType
   , (/), (/!), recip
   , powUsingMulRecip
   -- ** Tests
-  , specCanDiv, specCanDivNotMixed, CanDivX
+  , specCanDiv, specCanDivNotMixed
 )
 where
 
@@ -50,44 +50,34 @@
 {----- Field -----}
 
 type CanAddSubMulDivCNBy t s =
-  (CanAddSubMulBy t s, CanDivCNBy t s)
-
-type FieldPre t =
-    (Ring t,
-     CanDivCNSameType t, CanRecipCNSameType t,
-     CanAddSubMulDivCNBy t Rational,
-     CanAddSubMulDivCNBy t Integer,
-     CanAddSubMulDivCNBy t Int
-    )
-
-type Field t =
-  (FieldPre t,
-   CanEnsureCN t,
-   FieldPre (EnsureCN t))
+  (CanAddSubMulBy t s, CanAddSubMulBy (EnsureCN t) s, CanDivCNBy t s)
 
-type CertainlyEqFieldPre t =
-  (FieldPre t, CertainlyEqRing t)
+class
+  (Ring t,
+   CanDivCNSameType t, CanRecipCNSameType t,
+   CanAddSubMulDivCNBy t Rational,
+   CanAddSubMulDivCNBy t Integer,
+   CanAddSubMulDivCNBy t Int
+  )
+  =>
+  Field t
 
-type CertainlyEqField t =
-  (CertainlyEqFieldPre t,
-   CanEnsureCN t,
-   CertainlyEqFieldPre (EnsureCN t))
+instance Field Rational
+instance Field (CN Rational)
 
-type OrderedFieldPre t =
-  (FieldPre t, OrderedRing t, HasOrder t Rational)
+class
+  (Field t, OrderedRing t, HasOrder t Rational, HasOrder (EnsureCN t) Rational)
+  => OrderedField t
 
-type OrderedField t =
-  (OrderedFieldPre t,
-   CanEnsureCN t,
-   OrderedFieldPre (EnsureCN t))
+instance OrderedField Rational
+instance OrderedField (CN Rational)
 
-type OrderedCertainlyFieldPre t =
-  (CertainlyEqFieldPre t, OrderedCertainlyRing t, HasOrderCertainly t Rational)
+class
+  (Field t, OrderedCertainlyRing t, HasOrderCertainly t Rational, HasOrderCertainly (EnsureCN t) Rational)
+  => OrderedCertainlyField t
 
-type OrderedCertainlyField t =
-  (OrderedCertainlyFieldPre t,
-   CanEnsureCN t,
-   OrderedCertainlyFieldPre (EnsureCN t))
+instance OrderedCertainlyField Rational
+instance OrderedCertainlyField (CN Rational)
 
 {---- Division -----}
 
@@ -102,9 +92,10 @@
   type DivType t1 t2 = EnsureCN (DivTypeNoCN t1 t2)
   divide :: t1 -> t2 -> DivType t1 t2
   default divide ::
-    (CanTestZero t2, CanEnsureCN (DivTypeNoCN t1 t2))
+    (CanTestZero t2, CanEnsureCN (DivTypeNoCN t1 t2)
+    , DivType t1 t2 ~ EnsureCN (DivTypeNoCN t1 t2))
     =>
-    t1 -> t2 -> EnsureCN (DivTypeNoCN t1 t2)
+    t1 -> t2 -> DivType t1 t2
   divide = divideCN divideNoCN
 
 divideCN ::
@@ -131,46 +122,50 @@
   (CanDiv Integer t)
 
 type CanRecipSameType t =
-  (CanDiv Integer t, DivType Integer t ~ t)
+  (CanDiv Integer t, DivType Integer t ~ t, DivTypeNoCN Integer t ~ t)
 
 type CanRecipCNSameType t =
-  (CanDiv Integer t, DivType Integer t ~ EnsureCN t)
+  (CanDiv Integer t, DivType Integer t ~ EnsureCN t, DivTypeNoCN Integer t ~ t
+  ,CanEnsureCN t
+  ,CanDiv Integer (EnsureCN t), DivType Integer (EnsureCN t) ~ EnsureCN t, DivTypeNoCN Integer (EnsureCN t) ~ (EnsureCN t))
 
 recip :: (CanRecip t) => t -> DivType Integer t
 recip = divide 1
 
 type CanDivBy t1 t2 =
-  (CanDiv t1 t2, DivType t1 t2 ~ t1)
+  (CanDiv t1 t2, DivType t1 t2 ~ t1, DivTypeNoCN t1 t2 ~ t1)
 type CanDivSameType t =
   CanDivBy t t
 
 type CanDivCNBy t1 t2 =
-  (CanDiv t1 t2, DivType t1 t2 ~ EnsureCN t1)
+  (CanDiv t1 t2, DivType t1 t2 ~ EnsureCN t1, DivTypeNoCN t1 t2 ~ t1
+  , CanEnsureCN t1
+  , CanDiv (EnsureCN t1) t2, DivType (EnsureCN t1) t2 ~ EnsureCN t1, DivTypeNoCN (EnsureCN t1) t2 ~ (EnsureCN t1))
 type CanDivCNSameType t =
-  CanDivCNBy t t
-
-{-| Compound type constraint useful for test definition. -}
-type CanDivX t1 t2 =
-  (CanDiv t1 t2,
-   Show t1, Arbitrary t1,
-   Show t2, Arbitrary t2,
-   Show (DivType t1 t2),
-   HasEqCertainly t1 (DivType t1 t2))
+  (CanDivCNBy t t
+  , CanDiv (EnsureCN t) (EnsureCN t), DivType (EnsureCN t) (EnsureCN t) ~ EnsureCN t, DivTypeNoCN (EnsureCN t) (EnsureCN t) ~ (EnsureCN t))
 
 {-|
   HSpec properties that each implementation of CanDiv should satisfy.
  -}
 specCanDiv ::
-  (CanRecip t1, CanRecip (DivType Integer t1),
-   Show (DivType Integer (DivType Integer t1)),
-   HasEqCertainly t1 (DivType Integer (DivType Integer t1)),
+  (Show t1, Show t2, Show (DivType Integer (DivType Integer t1)),
+   Show (DivType t1 t2), Show (DivType t1 t1),
+   Show (MulType t1 (DivType t1 t2)), Arbitrary t1, Arbitrary t2,
+   ConvertibleExactly Integer t1, ConvertibleExactly Integer t2,
+   CanTestCertainly
+     (EqCompareType (DivType Integer (DivType Integer t1)) t1),
+   CanTestCertainly (EqCompareType (DivType t1 t2) t1),
+   CanTestCertainly (EqCompareType (DivType t1 t1) t1),
+   CanTestCertainly
+     (EqCompareType (DivType t1 t2) (MulType t1 (DivType t1 t2))),
+   HasEqAsymmetric (DivType Integer (DivType Integer t1)) t1,
+   HasEqAsymmetric (DivType t1 t2) t1,
+   HasEqAsymmetric (DivType t1 t2) (MulType t1 (DivType t1 t2)),
+   HasEqAsymmetric (DivType t1 t1) t1, CanTestZero t1, CanTestZero t2,
    CanTestZero (DivType Integer t1),
-   CanDivX t1 t2,
-   CanTestZero t1,
-   CanTestZero t2,
-   CanDivX t1 t1,
-   CanMulX t1 (DivType t1 t2),
-   ConvertibleExactly Integer t2, ConvertibleExactly Integer t1)
+   CanMulAsymmetric t1 (DivType t1 t2), CanDiv t1 t1, CanDiv t1 t2,
+   CanDiv Integer t1, CanDiv Integer (DivType Integer t1))
   =>
   T t1 -> T t2 -> Spec
 specCanDiv (T typeName1 :: T t1) (T typeName2 :: T t2) =
@@ -198,17 +193,23 @@
   HSpec properties that each implementation of CanDiv should satisfy.
  -}
 specCanDivNotMixed ::
-  (CanRecip t, CanRecip (DivType Integer t),
-   Show (DivType Integer (DivType Integer t)),
-   HasEqCertainly t (DivType Integer (DivType Integer t)),
-   CanTestZero (DivType Integer t),
-   CanDivX t t,
-   CanTestZero t,
-   CanMulX t (DivType t t),
-   ConvertibleExactly Integer t)
+  (Show t, Show (DivType Integer (DivType Integer t)),
+   Show (DivType t t), Show (MulType t (DivType t t)), Arbitrary t,
+   ConvertibleExactly Integer t,
+   CanTestCertainly
+     (EqCompareType (DivType Integer (DivType Integer t)) t),
+   CanTestCertainly (EqCompareType (DivType t t) t),
+   CanTestCertainly
+     (EqCompareType (DivType t t) (MulType t (DivType t t))),
+   HasEqAsymmetric (DivType Integer (DivType Integer t)) t,
+   HasEqAsymmetric (DivType t t) t,
+   HasEqAsymmetric (DivType t t) (MulType t (DivType t t)),
+   CanTestZero t, CanTestZero (DivType Integer t),
+   CanMulAsymmetric t (DivType t t), CanDiv t t, CanDiv Integer t,
+   CanDiv Integer (DivType Integer t))
   =>
   T t -> Spec
-specCanDivNotMixed t = specCanDiv t t
+specCanDivNotMixed (t :: T t) = specCanDiv t t
 
 instance CanDiv Int Int where
   type DivTypeNoCN Int Int = Rational
@@ -282,6 +283,7 @@
 
 instance
   (CanDiv a b
+  , CanEnsureCE es a, CanEnsureCE es b
   , CanEnsureCE es (DivType a b)
   , CanEnsureCE es (DivTypeNoCN a b)
   , SuitableForCE es)
@@ -296,15 +298,15 @@
   divideNoCN = lift2CE divideNoCN
 
 powUsingMulRecip ::
-  (CanBeInteger e, HasIntegers t,
+  (CanBeInteger e,
    CanRecipCNSameType t, CanMulSameType t, CanEnsureCN t)
    =>
-   t -> e -> EnsureCN t
-powUsingMulRecip x nPre
-  | n < 0 = recip $ powUsingMul x (negate n)
-  | otherwise = ensureCN $ powUsingMul x n
+   t -> t -> e -> EnsureCN t
+powUsingMulRecip one x nPre
+  | n < 0 = recip $ powUsingMul one x (negate n)
+  | otherwise = ensureCN $ powUsingMul one x n
   where
-    n = integer nPre
+  n = integer nPre
 
 $(declForTypes
   [[t| Integer |], [t| Int |], [t| Rational |], [t| Double |]]
@@ -312,6 +314,7 @@
 
     instance
       (CanDiv $t b
+      , CanEnsureCE es b
       , CanEnsureCE es (DivType $t b)
       , CanEnsureCE es (DivTypeNoCN $t b)
       , SuitableForCE es)
@@ -327,6 +330,7 @@
 
     instance
       (CanDiv a $t
+      , CanEnsureCE es a
       , CanEnsureCE es (DivType a $t)
       , CanEnsureCE es (DivTypeNoCN a $t)
       , SuitableForCE es)
diff --git a/src/Numeric/MixedTypes/Literals.hs b/src/Numeric/MixedTypes/Literals.hs
--- a/src/Numeric/MixedTypes/Literals.hs
+++ b/src/Numeric/MixedTypes/Literals.hs
@@ -38,7 +38,7 @@
   -- * Fixed-type literals
   fromInteger, fromRational
   -- * Generalised if-then-else
-  , HasIfThenElse(..)
+  , HasIfThenElse(..), HasIfThenElseSameType
   -- * Convenient conversions
   , CanBeInteger, integer, integers, HasIntegers, fromInteger_
   , CanBeInt, int, ints
@@ -91,7 +91,12 @@
   Restore if-then-else with RebindableSyntax
 -}
 class HasIfThenElse b t where
-  ifThenElse :: b -> t -> t -> t
+  type IfThenElseType b t
+  type IfThenElseType b t = t
+  ifThenElse :: b -> t -> t -> IfThenElseType b t
+
+type HasIfThenElseSameType b t =
+  (HasIfThenElse b t, IfThenElseType b t ~ t)
 
 instance HasIfThenElse Bool t where
   ifThenElse b e1 e2
diff --git a/src/Numeric/MixedTypes/MinMaxAbs.hs b/src/Numeric/MixedTypes/MinMaxAbs.hs
--- a/src/Numeric/MixedTypes/MinMaxAbs.hs
+++ b/src/Numeric/MixedTypes/MinMaxAbs.hs
@@ -17,7 +17,7 @@
   CanMinMax, CanMinMaxAsymmetric(..), CanMinMaxThis, CanMinMaxSameType
   , minimum, maximum
   -- ** Tests
-  , specCanMinMax, specCanMinMaxNotMixed, CanMinMaxX, CanMinMaxXX
+  , specCanMinMax, specCanMinMaxNotMixed
   -- * Absolute value
   , CanAbs(..), CanAbsSameType
   -- ** Tests
@@ -59,9 +59,9 @@
   type MinMaxType t1 t2 = t1 -- default
   min :: t1 -> t2 -> MinMaxType t1 t2
   max :: t1 -> t2 -> MinMaxType t1 t2
-  default min :: (MinMaxType t1 t2 ~ t1, t1~t2, P.Ord t1) => t1 -> t1 -> t1
+  default min :: (MinMaxType t1 t2 ~ t1, t1~t2, P.Ord t1) => t1 -> t2 -> MinMaxType t1 t2
   min = P.min
-  default max :: (MinMaxType t1 t2 ~ t1, t1~t2, P.Ord t1) => t1 -> t1 -> t1
+  default max :: (MinMaxType t1 t2 ~ t1, t1~t2, P.Ord t1) => t1 -> t2 -> MinMaxType t1 t2
   max = P.max
 
 type CanMinMaxThis t1 t2 =
@@ -77,36 +77,39 @@
 minimum (x:xs) = List.foldl' min x xs
 minimum [] = error $ "minimum: empty list"
 
-{-| Compound type constraint useful for test definition. -}
-type CanMinMaxX t1 t2 =
-  (CanMinMax t1 t2,
-   Show t1, Arbitrary t1,
-   Show t2, Arbitrary t2,
-   Show (MinMaxType t1 t2),
-   HasEqCertainly t1 t1,
-   HasEqCertainly t2 t2,
-   HasEqCertainly t1 (MinMaxType t1 t2),
-   HasEqCertainly t2 (MinMaxType t1 t2),
-   HasEqCertainly (MinMaxType t1 t2) (MinMaxType t1 t2),
-   HasOrderCertainly t1 (MinMaxType t1 t2),
-   HasOrderCertainly t2 (MinMaxType t1 t2),
-   HasOrderCertainly (MinMaxType t1 t2) (MinMaxType t1 t2))
-
-{-| Compound type constraint useful for test definition. -}
-type CanMinMaxXX t1 t2 =
-  (CanMinMaxX t1 t2,
-   HasEqCertainly (MinMaxType t1 t2) (MinMaxType t2 t1))
-
 {-|
   HSpec properties that each implementation of CanMinMax should satisfy.
  -}
 specCanMinMax ::
-  (CanMinMaxXX t1 t1,
-   CanMinMaxXX t1 t2,
-   CanMinMaxXX t1 t3, CanMinMaxXX t2 t3,
-   CanMinMaxXX t1 (MinMaxType t2 t3),
-   CanMinMaxXX (MinMaxType t1 t2) t3,
-   HasEqCertainly (MinMaxType t1 (MinMaxType t2 t3)) (MinMaxType (MinMaxType t1 t2) t3))
+ (Show t1, Show t2, Show t3, Show (MinMaxType t1 t2),
+  Show (MinMaxType t1 t1), Show (MinMaxType t2 t1),
+  Show (MinMaxType t1 (MinMaxType t2 t3)),
+  Show (MinMaxType (MinMaxType t1 t2) t3), Arbitrary t1,
+  Arbitrary t2, Arbitrary t3, CanTestCertainly (EqCompareType t1 t1),
+  CanTestCertainly (EqCompareType t2 t2),
+  CanTestCertainly (OrderCompareType (MinMaxType t1 t2) t2),
+  CanTestCertainly (OrderCompareType (MinMaxType t1 t2) t1),
+  CanTestCertainly (EqCompareType (MinMaxType t1 t1) t1),
+  CanTestCertainly
+    (EqCompareType (MinMaxType t1 t2) (MinMaxType t2 t1)),
+  CanTestCertainly (EqCompareType t3 t3),
+  CanTestCertainly
+    (EqCompareType
+       (MinMaxType t1 (MinMaxType t2 t3))
+       (MinMaxType (MinMaxType t1 t2) t3)),
+  HasEqAsymmetric t1 t1, HasEqAsymmetric t2 t2,
+  HasEqAsymmetric t3 t3,
+  HasEqAsymmetric (MinMaxType t1 t2) (MinMaxType t2 t1),
+  HasEqAsymmetric (MinMaxType t1 t1) t1,
+  HasEqAsymmetric
+    (MinMaxType t1 (MinMaxType t2 t3))
+    (MinMaxType (MinMaxType t1 t2) t3),
+  HasOrderAsymmetric (MinMaxType t1 t2) t1,
+  HasOrderAsymmetric (MinMaxType t1 t2) t2,
+  CanMinMaxAsymmetric t1 t1, CanMinMaxAsymmetric t1 t2,
+  CanMinMaxAsymmetric t1 (MinMaxType t2 t3),
+  CanMinMaxAsymmetric t2 t1, CanMinMaxAsymmetric t2 t3,
+  CanMinMaxAsymmetric (MinMaxType t1 t2) t3)
   =>
   T t1 -> T t2 -> T t3 -> Spec
 specCanMinMax (T typeName1 :: T t1) (T typeName2 :: T t2) (T typeName3 :: T t3) =
@@ -155,9 +158,27 @@
   HSpec properties that each implementation of CanMinMax should satisfy.
  -}
 specCanMinMaxNotMixed ::
-  (CanMinMaxXX t t,
-   CanMinMaxXX t (MinMaxType t t),
-   HasEq (MinMaxType (MinMaxType t t) t) (MinMaxType t (MinMaxType t t)) )
+ (Show t, Show (MinMaxType t t),
+  Show (MinMaxType t (MinMaxType t t)),
+  Show (MinMaxType (MinMaxType t t) t), Arbitrary t,
+  CanTestCertainly (EqCompareType t t),
+  CanTestCertainly (OrderCompareType (MinMaxType t t) t),
+  CanTestCertainly (EqCompareType (MinMaxType t t) t),
+  CanTestCertainly
+    (EqCompareType (MinMaxType t t) (MinMaxType t t)),
+  CanTestCertainly
+    (EqCompareType
+       (MinMaxType t (MinMaxType t t))
+       (MinMaxType (MinMaxType t t) t)),
+  HasEqAsymmetric t t, HasEqAsymmetric (MinMaxType t t) t,
+  HasEqAsymmetric (MinMaxType t t) (MinMaxType t t),
+  HasEqAsymmetric
+    (MinMaxType t (MinMaxType t t))
+    (MinMaxType (MinMaxType t t) t),
+  HasOrderAsymmetric (MinMaxType t t) t,
+  CanMinMaxAsymmetric t t,
+  CanMinMaxAsymmetric t (MinMaxType t t),
+  CanMinMaxAsymmetric (MinMaxType t t) t)
   =>
   T t -> Spec
 specCanMinMaxNotMixed t = specCanMinMax t t t
@@ -210,6 +231,7 @@
 
 instance
   (CanMinMaxAsymmetric a b
+  , CanEnsureCE es a, CanEnsureCE es b
   , CanEnsureCE es (MinMaxType a b)
   , SuitableForCE es)
   =>
@@ -226,6 +248,7 @@
 
     instance
       (CanMinMaxAsymmetric $t b
+      , CanEnsureCE es b
       , CanEnsureCE es (MinMaxType $t b)
       , SuitableForCE es)
       =>
@@ -238,6 +261,7 @@
 
     instance
       (CanMinMaxAsymmetric a $t
+      , CanEnsureCE es a
       , CanEnsureCE es (MinMaxType a $t)
       , SuitableForCE es)
       =>
@@ -304,7 +328,7 @@
   type AbsType t
   type AbsType t = t -- default
   abs :: t -> AbsType t
-  default abs :: (AbsType t ~ t, P.Num t) => t -> t
+  default abs :: (AbsType t ~ t, P.Num t) => t -> AbsType t
   abs = P.abs
 
 type CanAbsSameType t = (CanAbs t, AbsType t ~ t)
@@ -316,6 +340,7 @@
 
 instance
   (CanAbs a
+  , CanEnsureCE es a
   , CanEnsureCE es (AbsType a)
   , SuitableForCE es)
   =>
diff --git a/src/Numeric/MixedTypes/Ord.hs b/src/Numeric/MixedTypes/Ord.hs
--- a/src/Numeric/MixedTypes/Ord.hs
+++ b/src/Numeric/MixedTypes/Ord.hs
@@ -20,7 +20,7 @@
   , (?<=?), (?<?), (?>=?), (?>?)
   , (!<=!), (!<!), (!>=!), (!>!)
   -- ** Tests
-  , specHasOrder, specHasOrderNotMixed, HasOrderX
+  , specHasOrder, specHasOrderNotMixed
   -- ** Specific comparisons
   , CanTestPosNeg(..)
 )
@@ -76,7 +76,7 @@
     type OrderCompareType a b = Bool -- default
     lessThan :: a -> b -> (OrderCompareType a b)
     -- default lessThan via Prelude for Bool:
-    default lessThan :: (OrderCompareType a b ~ Bool, a~b, P.Ord a) => a -> b -> Bool
+    default lessThan :: (OrderCompareType a b ~ Bool, a~b, P.Ord a) => a -> b -> OrderCompareType a b
     lessThan = (P.<)
     greaterThan :: a -> b -> (OrderCompareType a b)
     default greaterThan ::
@@ -85,7 +85,7 @@
     greaterThan a b = lessThan b a
     leq :: a -> b -> (OrderCompareType a b)
     -- default lessThan via Prelude for Bool:
-    default leq :: (OrderCompareType a b ~ Bool, a~b, P.Ord a) => a -> b -> Bool
+    default leq :: (OrderCompareType a b ~ Bool, a~b, P.Ord a) => a -> b -> OrderCompareType a b
     leq = (P.<=)
     geq :: a -> b -> (OrderCompareType a b)
     default geq ::
@@ -127,18 +127,21 @@
 (!<=!) :: (HasOrderCertainlyAsymmetric a b) => a -> b -> Bool
 a !<=! b = isCertainlyTrue $ a <= b
 
-{-| Compound type constraint useful for test definition. -}
-type HasOrderX t1 t2 =
-  (HasOrderCertainly t1 t2, Show t1, QC.Arbitrary t1, Show t2, QC.Arbitrary t2)
-
 {-|
   HSpec properties that each implementation of 'HasOrder' should satisfy.
  -}
 specHasOrder ::
-  (HasOrderX t1 t1,
-   HasOrderX t1 t2,
-   HasOrderX t1 t3, HasOrderX t2 t3,
-   CanAndOrX (OrderCompareType t1 t2) (OrderCompareType t2 t3))
+  (Show t1, Show t2, Show t3, QC.Arbitrary t1, QC.Arbitrary t2,
+   QC.Arbitrary t3, CanTestCertainly (OrderCompareType t1 t1),
+   CanTestCertainly (OrderCompareType t1 t2),
+   CanTestCertainly (OrderCompareType t2 t1),
+   CanTestCertainly (OrderCompareType t2 t3),
+   CanTestCertainly
+     (AndOrType (OrderCompareType t1 t2) (OrderCompareType t2 t3)),
+   CanAndOrAsymmetric
+     (OrderCompareType t1 t2) (OrderCompareType t2 t3),
+   HasOrderAsymmetric t1 t1, HasOrderAsymmetric t1 t2,
+   HasOrderAsymmetric t2 t1, HasOrderAsymmetric t2 t3)
   =>
   T t1 -> T t2 -> T t3 -> Spec
 specHasOrder (T typeName1 :: T t1) (T typeName2 :: T t2) (T typeName3 :: T t3) =
@@ -166,12 +169,18 @@
   HSpec properties that each implementation of 'HasOrder' should satisfy.
  -}
 specHasOrderNotMixed ::
-  (HasOrderX t t,
-   CanAndOrX (OrderCompareType t t) (OrderCompareType t t))
+  (Show t, QC.Arbitrary t, CanTestCertainly (OrderCompareType t t),
+   CanTestCertainly
+     (AndOrType (OrderCompareType t t) (OrderCompareType t t)),
+   HasOrderAsymmetric t t)
   =>
   T t -> Spec
-specHasOrderNotMixed t = specHasOrder t t t
+specHasOrderNotMixed (t :: T t) = specHasOrder t t t
 
+instance HasOrderAsymmetric () () where
+  lessThan _ _ = False
+  leq _ _ = True
+
 instance HasOrderAsymmetric Int Int
 instance HasOrderAsymmetric Integer Integer
 instance HasOrderAsymmetric Rational Rational
@@ -214,11 +223,12 @@
 
 instance
   (HasOrderAsymmetric a b
+  , CanEnsureCE es a, CanEnsureCE es b
   , CanEnsureCE es (OrderCompareType a b)
   , IsBool (EnsureCE es (OrderCompareType a b))
   , SuitableForCE es)
   =>
-  HasOrderAsymmetric (CollectErrors es a) (CollectErrors es  b)
+  HasOrderAsymmetric (CollectErrors es a) (CollectErrors es b)
   where
   type OrderCompareType (CollectErrors es a) (CollectErrors es b) =
     EnsureCE es (OrderCompareType a b)
@@ -233,6 +243,7 @@
 
     instance
       (HasOrderAsymmetric $t b
+      , CanEnsureCE es b
       , CanEnsureCE es (OrderCompareType $t b)
       , IsBool (EnsureCE es (OrderCompareType $t b))
       , SuitableForCE es)
@@ -248,6 +259,7 @@
 
     instance
       (HasOrderAsymmetric a $t
+      , CanEnsureCE es a
       , CanEnsureCE es (OrderCompareType a $t)
       , IsBool (EnsureCE es (OrderCompareType a $t))
       , SuitableForCE es)
diff --git a/src/Numeric/MixedTypes/Ring.hs b/src/Numeric/MixedTypes/Ring.hs
--- a/src/Numeric/MixedTypes/Ring.hs
+++ b/src/Numeric/MixedTypes/Ring.hs
@@ -14,18 +14,18 @@
 module Numeric.MixedTypes.Ring
 (
   -- * Ring
-  CanAddSubMulBy, Ring, CertainlyEqRing, OrderedRing, OrderedCertainlyRing
+  CanAddSubMulBy, Ring, OrderedRing, OrderedCertainlyRing
   -- * Multiplication
   , CanMul, CanMulAsymmetric(..), CanMulBy, CanMulSameType
   , (*), product
   -- ** Tests
-  , specCanMul, specCanMulNotMixed, specCanMulSameType, CanMulX
+  , specCanMul, specCanMulNotMixed, specCanMulSameType
   -- * Exponentiation
   , CanPow(..), CanPowBy, CanPowCNBy
   , (^), (^!)
-  , powUsingMul
+  , powUsingMul, integerPowCN
   -- ** Tests
-  , specCanPow, CanPowX
+  , specCanPow
 )
 where
 
@@ -55,7 +55,7 @@
 type CanAddSubMulBy t s =
   (CanAddThis t s, CanSubThis t s, CanMulBy t s)
 
-type Ring t =
+type RingPre t =
   (CanNegSameType t, CanAddSameType t, CanSubSameType t, CanMulSameType t,
    CanPowCNBy t Integer, CanPowCNBy t Int,
    HasEq t t,
@@ -63,16 +63,57 @@
    HasEq t Int, CanAddSubMulBy t Int,
    HasIntegers t)
 
-type CertainlyEqRing t =
-  (Ring t, HasEqCertainly t t, HasEqCertainly t Int, HasEqCertainly t Integer)
+class
+  (RingPre t,
+   CanEnsureCN t,
+   RingPre (EnsureCN t))
+  =>
+  Ring t
 
-type OrderedRing t =
-  (Ring t, HasOrder t t, HasOrder t Int, HasOrder t Integer)
+instance Ring Integer
+instance Ring (CN Integer)
+instance Ring Rational
+instance Ring (CN Rational)
 
-type OrderedCertainlyRing t =
-  (CertainlyEqRing t, HasOrderCertainly t t, HasOrderCertainly t Int, HasOrderCertainly t Integer,
-  CanTestPosNeg t)
+class
+  (Ring t
+  , HasEq t t
+  , HasEq (EnsureCN t) t
+  , HasEq t (EnsureCN t)
+  , HasEq t Int, HasEq t Integer
+  , HasEq (EnsureCN t) Int, HasEq (EnsureCN t) Integer
+  , HasOrder t t
+  , HasOrder (EnsureCN t) t
+  , HasOrder t (EnsureCN t)
+  , HasOrder t Int, HasOrder t Integer
+  , HasOrder (EnsureCN t) Int, HasOrder (EnsureCN t) Integer)
+  => OrderedRing t
 
+instance OrderedRing Integer
+instance OrderedRing (CN Integer)
+instance OrderedRing Rational
+instance OrderedRing (CN Rational)
+
+class
+  (Ring t
+  , HasEqCertainly t t
+  , HasEqCertainly (EnsureCN t) t
+  , HasEqCertainly t (EnsureCN t)
+  , HasEqCertainly t Int, HasEq t Integer
+  , HasEqCertainly (EnsureCN t) Int, HasEq (EnsureCN t) Integer
+  , HasOrderCertainly t t
+  , HasOrderCertainly (EnsureCN t) t
+  , HasOrderCertainly t (EnsureCN t)
+  , HasOrderCertainly t Int, HasOrderCertainly t Integer
+  , HasOrderCertainly (EnsureCN t) Int, HasOrderCertainly (EnsureCN t) Integer
+  , CanTestPosNeg t)
+  => OrderedCertainlyRing t
+
+instance OrderedCertainlyRing Integer
+instance OrderedCertainlyRing (CN Integer)
+instance OrderedCertainlyRing Rational
+instance OrderedCertainlyRing (CN Rational)
+
 {---- Multiplication -----}
 
 type CanMul t1 t2 =
@@ -87,7 +128,7 @@
   type MulType t1 t2
   type MulType t1 t2 = t1 -- default
   mul :: t1 -> t2 -> MulType t1 t2
-  default mul :: (MulType t1 t2 ~ t1, t1~t2, P.Num t1) => t1 -> t1 -> t1
+  default mul :: (MulType t1 t2 ~ t1, t1~t2, P.Num t1) => t1 -> t2 -> MulType t1 t2
   mul = (P.*)
 
 infixl 8  ^, ^!
@@ -96,14 +137,6 @@
 (*) :: (CanMulAsymmetric t1 t2) => t1 -> t2 -> MulType t1 t2
 (*) = mul
 
-(^) :: (CanPow t1 t2) => t1 -> t2 -> PowType t1 t2
-(^) = pow
-
-{-| Like `^` but throwing an exception if the power is undefined. -}
-(^!) :: (CanPow t1 t2, Show (PowType t1 t2), CanEnsureCN (PowType t1 t2)) =>
-  t1 -> t2 -> EnsureNoCN (PowType t1 t2)
-a ^! b = (~!) (a ^ b)
-
 type CanMulBy t1 t2 =
   (CanMul t1 t2, MulType t1 t2 ~ t1)
 type CanMulSameType t =
@@ -112,34 +145,38 @@
 product :: (CanMulSameType t, ConvertibleExactly Integer t) => [t] -> t
 product xs = List.foldl' mul (convertExactly 1) xs
 
-{-| Compound type constraint useful for test definition. -}
-type CanMulX t1 t2 =
-  (CanMul t1 t2,
-   Show t1, Arbitrary t1,
-   Show t2, Arbitrary t2,
-   Show (MulType t1 t2),
-   HasEqCertainly t1 (MulType t1 t2),
-   HasEqCertainly t2 (MulType t1 t2),
-   HasEqCertainly (MulType t1 t2) (MulType t1 t2),
-   HasOrderCertainly t1 (MulType t1 t2),
-   HasOrderCertainly t2 (MulType t1 t2),
-   HasOrderCertainly (MulType t1 t2) (MulType t1 t2))
-
 {-|
   HSpec properties that each implementation of CanMul should satisfy.
  -}
 specCanMul ::
-  (CanMulX t1 t2,
-   CanMulX t1 t3,
-   CanMulX t2 t3,
-   CanMulX t1 (MulType t2 t3),
-   CanMulX (MulType t1 t2) t3,
-   HasEqCertainly (MulType t1 (MulType t2 t3)) (MulType (MulType t1 t2) t3),
-   CanAdd t2 t3,
-   CanMulX t1 (AddType t2 t3),
-   CanAddX (MulType t1 t2) (MulType t1 t3),
-   HasEqCertainly (MulType t1 (AddType t2 t3)) (AddType (MulType t1 t2) (MulType t1 t3)),
-   ConvertibleExactly Integer t2)
+  (Show t1, Show t2, Show t3, Show (MulType t1 t2),
+   Show (MulType t2 t1), Show (MulType t1 (MulType t2 t3)),
+   Show (MulType (MulType t1 t2) t3),
+   Show (MulType t1 (AddType t2 t3)),
+   Show (AddType (MulType t1 t2) (MulType t1 t3)), Arbitrary t1,
+   Arbitrary t2, Arbitrary t3, ConvertibleExactly Integer t2,
+   CanTestCertainly (EqCompareType (MulType t1 t2) t1),
+   CanTestCertainly (EqCompareType (MulType t1 t2) (MulType t2 t1)),
+   CanTestCertainly
+     (EqCompareType
+        (MulType t1 (MulType t2 t3)) (MulType (MulType t1 t2) t3)),
+   CanTestCertainly
+     (EqCompareType
+        (MulType t1 (AddType t2 t3))
+        (AddType (MulType t1 t2) (MulType t1 t3))),
+   HasEqAsymmetric (MulType t1 t2) t1,
+   HasEqAsymmetric (MulType t1 t2) (MulType t2 t1),
+   HasEqAsymmetric
+     (MulType t1 (MulType t2 t3)) (MulType (MulType t1 t2) t3),
+   HasEqAsymmetric
+     (MulType t1 (AddType t2 t3))
+     (AddType (MulType t1 t2) (MulType t1 t3)),
+   CanAddAsymmetric t2 t3,
+   CanAddAsymmetric (MulType t1 t2) (MulType t1 t3),
+   CanMulAsymmetric t1 t2, CanMulAsymmetric t1 t3,
+   CanMulAsymmetric t1 (MulType t2 t3),
+   CanMulAsymmetric t1 (AddType t2 t3), CanMulAsymmetric t2 t1,
+   CanMulAsymmetric t2 t3, CanMulAsymmetric (MulType t1 t2) t3)
   =>
   T t1 -> T t2 -> T t3 -> Spec
 specCanMul (T typeName1 :: T t1) (T typeName2 :: T t2) (T typeName3 :: T t3) =
@@ -163,24 +200,39 @@
   HSpec properties that each implementation of CanMul should satisfy.
  -}
 specCanMulNotMixed ::
-  (CanMulX t t,
-   CanMulX t (MulType t t),
-   HasEqCertainly (MulType (MulType t t) t) (MulType t (MulType t t)),
-   CanAdd t t,
-   CanMulX t (AddType t t),
-   CanAddX (MulType t t) (MulType t t),
-   HasEqCertainly (MulType t (AddType t t)) (AddType (MulType t t) (MulType t t)),
-   ConvertibleExactly Integer t)
+  (Show t, Show (MulType t t), Show (MulType t (MulType t t)),
+   Show (MulType (MulType t t) t), Show (MulType t (AddType t t)),
+   Show (AddType (MulType t t) (MulType t t)), Arbitrary t,
+   ConvertibleExactly Integer t,
+   CanTestCertainly (EqCompareType (MulType t t) t),
+   CanTestCertainly (EqCompareType (MulType t t) (MulType t t)),
+   CanTestCertainly
+     (EqCompareType
+        (MulType t (MulType t t)) (MulType (MulType t t) t)),
+   CanTestCertainly
+     (EqCompareType
+        (MulType t (AddType t t)) (AddType (MulType t t) (MulType t t))),
+   HasEqAsymmetric (MulType t t) t,
+   HasEqAsymmetric (MulType t t) (MulType t t),
+   HasEqAsymmetric
+     (MulType t (MulType t t)) (MulType (MulType t t) t),
+   HasEqAsymmetric
+     (MulType t (AddType t t)) (AddType (MulType t t) (MulType t t)),
+   CanAddAsymmetric t t, CanAddAsymmetric (MulType t t) (MulType t t),
+   CanMulAsymmetric t t, CanMulAsymmetric t (MulType t t),
+   CanMulAsymmetric t (AddType t t),
+   CanMulAsymmetric (MulType t t) t)
   =>
   T t -> Spec
-specCanMulNotMixed t = specCanMul t t t
+specCanMulNotMixed (t :: T t) = specCanMul t t t
 
 {-|
   HSpec properties that each implementation of CanMulSameType should satisfy.
  -}
 specCanMulSameType ::
-  (ConvertibleExactly Integer t, Show t,
-   HasEqCertainly t t, CanMulSameType t)
+  (Show t, ConvertibleExactly Integer t,
+   CanTestCertainly (EqCompareType t t), HasEqAsymmetric t t,
+   CanMulAsymmetric t t, MulType t t ~ t)
    =>
    T t -> Spec
 specCanMulSameType (T typeName :: T t) =
@@ -256,6 +308,7 @@
 
 instance
   (CanMulAsymmetric a b
+  , CanEnsureCE es a, CanEnsureCE es b
   , CanEnsureCE es (MulType a b)
   , SuitableForCE es)
   =>
@@ -267,16 +320,33 @@
 
 {---- Exponentiation -----}
 
+(^) :: (CanPow t1 t2) => t1 -> t2 -> PowType t1 t2
+(^) = pow
+
+{-| Like `^` but throwing an exception if the power is undefined. -}
+(^!) :: (CanPow t1 t2) =>
+  t1 -> t2 -> PowTypeNoCN t1 t2
+(^!) = powNoCN
+
+
 {-|
   A replacement for Prelude's binary `P.^` and `P.^^`.  If @Num t1@ and @Integral t2@,
   then one can use the default implementation to mirror Prelude's @^@.
 -}
-class CanPow t1 t2 where
-  type PowType t1 t2
-  type PowType t1 t2 = t1 -- default
-  pow :: t1 -> t2 -> PowType t1 t2
-  -- default pow :: (PowType t1 t2 ~ t1, P.Num t1, P.Integral t2) => t1 -> t2 -> t1
-  -- pow = (P.^)
+class CanPow b e where
+  type PowTypeNoCN b e
+  type PowTypeNoCN b e = b -- default
+  powNoCN :: b -> e -> PowTypeNoCN b e
+  type PowType b e
+  type PowType b e = EnsureCN (PowTypeNoCN b e) -- default
+  pow :: b -> e -> PowType b e
+  default pow ::
+    (HasOrderCertainly b Integer, HasOrderCertainly e Integer,
+     HasEqCertainly b Integer, CanTestInteger e,
+     CanEnsureCN (PowTypeNoCN b e), PowType b e~EnsureCN (PowTypeNoCN b e))
+    =>
+    b -> e -> PowType b e
+  pow = powCN powNoCN
 
 integerPowCN ::
   (HasOrderCertainly b Integer, HasOrderCertainly e Integer,
@@ -320,12 +390,12 @@
 
 powUsingMul ::
   (CanBeInteger e,
-   CanMulSameType t, HasIntegers t)
+   CanMulSameType t)
    =>
-   t -> e -> t
-powUsingMul x nPre
+   t -> t -> e -> t
+powUsingMul one x nPre
   | n < 0 = error $ "powUsingMul is not defined for negative exponent " ++ show n
-  | n == 0 = convertExactly 1
+  | n == 0 = one
   | otherwise = aux n
   where
     n = integer nPre
@@ -337,31 +407,32 @@
         let s = aux ((m-1) `div` 2) in x * s * s
 
 type CanPowBy t1 t2 =
-  (CanPow t1 t2, PowType t1 t2 ~ t1)
+  (CanPow t1 t2, PowType t1 t2 ~ t1, PowTypeNoCN t1 t2 ~ t1)
 
 type CanPowCNBy t1 t2 =
-  (CanPow t1 t2, PowType t1 t2 ~ EnsureCN t1)
-
-{-| Compound type constraint useful for test definition. -}
-type CanPowX t1 t2 =
-  (CanPow t1 t2,
-   Show t1, Arbitrary t1,
-   Show t2, Arbitrary t2,
-   Show (PowType t1 t2))
+  (CanPow t1 t2, PowType t1 t2 ~ EnsureCN t1, PowTypeNoCN t1 t2 ~ t1
+  , CanEnsureCN t1
+  , CanPow (EnsureCN t1) t2, PowType (EnsureCN t1) t2 ~ EnsureCN t1
+  , PowTypeNoCN (EnsureCN t1) t2 ~ (EnsureCN t1))
 
 {-|
   HSpec properties that each implementation of CanPow should satisfy.
  -}
 specCanPow ::
-  (CanPowX t1 t2,
-   HasEqCertainly t1 (PowType t1 t2),
-   ConvertibleExactly Integer t1,
-   ConvertibleExactly Integer t2,
-   CanTestPosNeg t2,
-   CanAdd t2 Integer,
-   CanMulX t1 (PowType t1 t2),
-   CanPowX t1 (AddType t2 Integer),
-   HasEqCertainly (MulType t1 (PowType t1 t2)) (PowType t1 (AddType t2 Integer)))
+  (Show t1, Show t2, Show (PowType t1 t2),
+   Show (MulType t1 (PowType t1 t2)),
+   Show (PowType t1 (AddType t2 Integer)), Arbitrary t1, Arbitrary t2,
+   ConvertibleExactly Integer t1, ConvertibleExactly Integer t2,
+   CanTestCertainly (EqCompareType (PowType t1 t2) t1),
+   CanTestCertainly
+     (EqCompareType
+        (MulType t1 (PowType t1 t2)) (PowType t1 (AddType t2 Integer))),
+   HasEqAsymmetric (PowType t1 t2) t1,
+   HasEqAsymmetric
+     (MulType t1 (PowType t1 t2)) (PowType t1 (AddType t2 Integer)),
+   CanTestPosNeg t2, CanAddAsymmetric t2 Integer, CanPow t1 t2,
+   CanPow t1 (AddType t2 Integer),
+   CanMulAsymmetric t1 (PowType t1 t2))
   =>
   T t1 -> T t2 -> Spec
 specCanPow (T typeName1 :: T t1) (T typeName2 :: T t2) =
@@ -385,25 +456,31 @@
   (?==?$) = printArgsIfFails2 "?==?" (?==?)
 
 instance CanPow Integer Integer where
-  type PowType Integer Integer = CN Integer
+  powNoCN = (P.^)
   pow = integerPowCN (P.^)
 instance CanPow Integer Int where
-  type PowType Integer Int = CN Integer
+  powNoCN = (P.^)
   pow = integerPowCN (P.^)
 instance CanPow Int Integer where
-  type PowType Int Integer = CN Integer
+  type PowTypeNoCN Int Integer = Integer
+  powNoCN x n = powNoCN (integer x) n
   pow x n = pow (integer x) n
 instance CanPow Int Int where
-  type PowType Int Int = CN Integer
+  type PowTypeNoCN Int Int = Integer
+  powNoCN x n = powNoCN (integer x) n
   pow x n = pow (integer x) n
 instance CanPow Rational Int where
-  type PowType Rational Int = CN Rational
-  pow = powCN (P.^^)
+  powNoCN = (P.^^)
 instance CanPow Rational Integer where
-  type PowType Rational Integer = CN Rational
-  pow = powCN (P.^^)
-instance CanPow Double Int where pow = (P.^^)
-instance CanPow Double Integer where pow = (P.^^)
+  powNoCN = (P.^^)
+instance CanPow Double Int where
+  powNoCN = (P.^^)
+  type PowType Double Int = Double
+  pow = (P.^^)
+instance CanPow Double Integer where
+  powNoCN = (P.^^)
+  type PowType Double Integer = Double
+  pow = (P.^^)
 
 -- instance (CanPow a b) => CanPow [a] [b] where
 --   type PowType [a] [b] = [PowType a b]
@@ -411,17 +488,25 @@
 --   pow _ _ = []
 
 instance (CanPow a b) => CanPow (Maybe a) (Maybe b) where
+  type PowTypeNoCN (Maybe a) (Maybe b) = Maybe (PowTypeNoCN a b)
+  powNoCN (Just x) (Just y) = Just (powNoCN x y)
+  powNoCN _ _ = Nothing
   type PowType (Maybe a) (Maybe b) = Maybe (PowType a b)
   pow (Just x) (Just y) = Just (pow x y)
   pow _ _ = Nothing
 
 instance
   (CanPow a b
+  , CanEnsureCE es a, CanEnsureCE es b
+  , CanEnsureCE es (PowTypeNoCN a b)
   , CanEnsureCE es (PowType a b)
   , SuitableForCE es)
   =>
   CanPow (CollectErrors es a) (CollectErrors es  b)
   where
+  type PowTypeNoCN (CollectErrors es a) (CollectErrors es b) =
+    EnsureCE es (PowTypeNoCN a b)
+  powNoCN = lift2CE powNoCN
   type PowType (CollectErrors es a) (CollectErrors es b) =
     EnsureCE es (PowType a b)
   pow = lift2CE pow
@@ -432,28 +517,39 @@
 
     instance
       (CanPow $t b
+      , CanEnsureCE es b
       , CanEnsureCE es (PowType $t b)
+      , CanEnsureCE es (PowTypeNoCN $t b)
       , SuitableForCE es)
       =>
       CanPow $t (CollectErrors es  b)
       where
+      type PowTypeNoCN $t (CollectErrors es  b) =
+        EnsureCE es (PowTypeNoCN $t b)
+      powNoCN = lift2TLCE powNoCN
       type PowType $t (CollectErrors es  b) =
         EnsureCE es (PowType $t b)
       pow = lift2TLCE pow
 
     instance
       (CanPow a $t
+      , CanEnsureCE es a
       , CanEnsureCE es (PowType a $t)
+      , CanEnsureCE es (PowTypeNoCN a $t)
       , SuitableForCE es)
       =>
       CanPow (CollectErrors es a) $t
       where
+      type PowTypeNoCN (CollectErrors es  a) $t =
+        EnsureCE es (PowTypeNoCN a $t)
+      powNoCN = lift2TCE powNoCN
       type PowType (CollectErrors es  a) $t =
         EnsureCE es (PowType a $t)
       pow = lift2TCE pow
 
     instance
       (CanMulAsymmetric $t b
+      , CanEnsureCE es b
       , CanEnsureCE es (MulType $t b)
       , SuitableForCE es)
       =>
@@ -465,6 +561,7 @@
 
     instance
       (CanMulAsymmetric a $t
+      , CanEnsureCE es a
       , CanEnsureCE es (MulType a $t)
       , SuitableForCE es)
       =>
