diff --git a/numhask-prelude.cabal b/numhask-prelude.cabal
--- a/numhask-prelude.cabal
+++ b/numhask-prelude.cabal
@@ -1,5 +1,5 @@
 name:           numhask-prelude
-version:        0.0.3.0
+version:        0.0.4.0
 synopsis:       A numeric prelude
 description:    A numeric prelude, combining protolude and numhask.
 category:       mathematics
@@ -39,6 +39,7 @@
     , tasty-quickcheck >= 0.9.2 && <1.0
   exposed-modules:
       NumHask.Prelude
+      NumHask.Error
       NumHask.Examples
       NumHask.Laws
   other-modules:
@@ -53,6 +54,7 @@
   default-extensions: NegativeLiterals NoImplicitPrelude OverloadedStrings UnicodeSyntax
   build-depends:
       base >=4.7 && <5
+    , QuickCheck >=2.8 && <3
     , doctest
     , numhask-prelude
     , tasty
diff --git a/src/NumHask/Error.hs b/src/NumHask/Error.hs
new file mode 100644
--- /dev/null
+++ b/src/NumHask/Error.hs
@@ -0,0 +1,9 @@
+{-# OPTIONS_GHC -Wno-deprecations #-}
+
+module NumHask.Error where
+
+import Protolude
+import Protolude.Panic (panic)
+
+impossible :: HasCallStack => Text -> a
+impossible = panic
diff --git a/src/NumHask/Examples.hs b/src/NumHask/Examples.hs
--- a/src/NumHask/Examples.hs
+++ b/src/NumHask/Examples.hs
@@ -1,5 +1,7 @@
 {-# LANGUAGE DataKinds #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
 {-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE RebindableSyntax #-}
 {-# LANGUAGE OverloadedLists #-}
 {-# OPTIONS_GHC -Wall #-}
 {-# OPTIONS_GHC -fno-warn-unused-imports #-}
@@ -55,6 +57,21 @@
 -- >>> 1 / fromIntegral (1::Int)
 -- 1.0
 --
+-- RebindableSyntax removes the Haskell98 link between literal numbers and base classes.  Literal numbers are pre-processed by ghc as `fromInteger 1` and `fromRational 1.0`.
+--
+-- >>> :t 1
+-- 1 :: Num p => p
+--
+-- >>> :t 1.0
+-- 1.0 :: Fractional p => p
+--
+-- >>> :set -XRebindableSyntax
+-- >>> :t 1
+-- 1 :: FromInteger a => a
+--
+-- >>> :t 1.0
+-- 1.0 :: FromRatio b => b
+--
 -- 'Float' and 'Double' are 'NumHask.Algebra.Fields.Field' instances.
 --
 -- >>> zero == 0.0
@@ -110,3 +127,15 @@
 -- 6 :+ 8
 -- >>> (1 :+ (-1)) / (2 :+ 2)
 -- 0.0 :+ (-0.5)
+
+newtype PositiveFloat = PositiveFloat { unPositive :: Float } deriving (Show, Eq, AdditiveMagma, AdditiveAssociative, AdditiveUnital, AdditiveCommutative, Additive, MultiplicativeMagma, MultiplicativeUnital, MultiplicativeAssociative, MultiplicativeCommutative, Multiplicative, MultiplicativeInvertible, MultiplicativeGroup, Distribution, Semiring, Ring, CRing, Semifield, UpperBoundedField)
+
+instance AdditiveInvertible PositiveFloat where
+  negate _ = nan
+
+instance AdditiveGroup PositiveFloat
+
+instance Bounded PositiveFloat where
+  minBound = zero
+  maxBound = infinity
+
diff --git a/src/NumHask/Laws.hs b/src/NumHask/Laws.hs
--- a/src/NumHask/Laws.hs
+++ b/src/NumHask/Laws.hs
@@ -1,4 +1,9 @@
+{-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE RebindableSyntax #-}
+{-# OPTIONS_GHC -fno-warn-type-defaults #-}
 
 module NumHask.Laws
   ( LawArity(..)
@@ -9,22 +14,28 @@
   , testLawOf2
   , idempotentLaws
   , additiveLaws
+  , additiveLaws_
   , additiveLawsFail
   , additiveGroupLaws
   , multiplicativeLaws
   , multiplicativeLawsFail
   , multiplicativeMonoidalLaws
   , multiplicativeGroupLaws
+  , multiplicativeGroupLaws_
   , distributionLaws
   , distributionLawsFail
   , integralLaws
+  , rationalLaws
   , signedLaws
-  , metricFloatLaws 
-  , metricComplexFloatLaws
-  , boundedFieldFloatLaws
+  , normedLaws
+  , normedBoundedLaws
+  , metricIntegralLaws
+  , metricIntegralBoundedLaws
+  , metricRationalLaws
+  , upperBoundedFieldLaws
+  , lowerBoundedFieldLaws
   , quotientFieldLaws 
   , expFieldLaws
-  , expFieldComplexLooseLaws  
   , additiveBasisLaws
   , additiveGroupBasisLaws
   , multiplicativeBasisLaws
@@ -33,20 +44,31 @@
   , additiveGroupModuleLaws
   , multiplicativeModuleLaws
   , multiplicativeGroupModuleLawsFail
-  , expFieldNaperianLaws
-  , metricNaperianFloatLaws
+  , expFieldContainerLaws
   , tensorProductLaws
   , banachLaws
   , hilbertLaws
   , semiringLaws
   , ringLaws
   , starSemiringLaws
+  , involutiveRingLaws
+  , integralsLaws
   ) where
 
 import NumHask.Prelude
 import Test.Tasty.QuickCheck hiding ((><))
 import Test.Tasty (TestName, TestTree)
 
+smallRational :: (FromRatio a) => a
+smallRational = 10.0
+
+smallRationalPower :: (FromRatio a) => a
+smallRationalPower = 6.0
+
+smallIntegralPower :: (FromInteger a) => a
+smallIntegralPower = 6
+
+-- | unification of law equations
 data LawArity a
   = Nonary Bool
   | Unary (a -> Bool)
@@ -55,18 +77,21 @@
   | Ornary (a -> a -> a -> a -> Bool)
   | Failiary (a -> Property)
 
+type Law a = (TestName, LawArity a)
+
+-- | unification of law equations with 2 types
 data LawArity2 a b
-  = Unary2 (a -> Bool)
-  | Binary2 (a -> b -> Bool)
-  | Ternary2 (a -> a -> b -> Bool)
-  | Ternary2' (a -> b -> b -> Bool)
-  | Ternary2'' (a -> a -> a -> Bool)
+  = Unary10 (a -> Bool)
+  | Unary01 (b -> Bool)
+  | Binary11 (a -> b -> Bool)
+  | Binary20 (a -> a -> Bool)
+  | Ternary21 (a -> a -> b -> Bool)
+  | Ternary12 (a -> b -> b -> Bool)
+  | Ternary30 (a -> a -> a -> Bool)
   | Quad31 (a -> a -> a -> b -> Bool)
   | Quad22 (a -> a -> b -> b -> Bool)
   | Failiary2 (a -> Property)
 
-type Law a = (TestName, LawArity a)
-
 type Law2 a b = (TestName, LawArity2 a b)
 
 testLawOf :: (Arbitrary a, Show a) => [a] -> Law a -> TestTree
@@ -82,11 +107,13 @@
   => [(a, b)]
   -> Law2 a b
   -> TestTree
-testLawOf2 _ (name, Unary2 f) = testProperty name f
-testLawOf2 _ (name, Binary2 f) = testProperty name f
-testLawOf2 _ (name, Ternary2 f) = testProperty name f
-testLawOf2 _ (name, Ternary2' f) = testProperty name f
-testLawOf2 _ (name, Ternary2'' f) = testProperty name f
+testLawOf2 _ (name, Unary10 f) = testProperty name f
+testLawOf2 _ (name, Unary01 f) = testProperty name f
+testLawOf2 _ (name, Binary11 f) = testProperty name f
+testLawOf2 _ (name, Binary20 f) = testProperty name f
+testLawOf2 _ (name, Ternary21 f) = testProperty name f
+testLawOf2 _ (name, Ternary12 f) = testProperty name f
+testLawOf2 _ (name, Ternary30 f) = testProperty name f
 testLawOf2 _ (name, Quad22 f) = testProperty name f
 testLawOf2 _ (name, Quad31 f) = testProperty name f
 testLawOf2 _ (name, Failiary2 f) = testProperty name f
@@ -98,7 +125,7 @@
   , ("idempotent: a * a == a", Unary (\a -> a * a == a))
   ]
 
--- additive
+-- | additive
 additiveLaws :: (Eq a, Additive a) => [Law a]
 additiveLaws =
   [ ( "associative: (a + b) + c = a + (b + c)"
@@ -108,6 +135,17 @@
   , ("commutative: a + b == b + a", Binary (\a b -> a + b == b + a))
   ]
 
+-- | additive with approximate association equality
+additiveLaws_ :: (Epsilon a) => [Law a]
+additiveLaws_ =
+  [ ( "associative: (a + b) + c ≈ a + (b + c)"
+    , Ternary (\a b c -> (a + b) + c ≈ a + (b + c)))
+  , ("left id: zero + a = a", Unary (\a -> zero + a == a))
+  , ("right id: a + zero = a", Unary (\a -> a + zero == a))
+  , ("commutative: a + b == b + a", Binary (\a b -> a + b == b + a))
+  ]
+
+-- | additive laws with a failure on association
 additiveLawsFail :: (Eq a, Additive a, Show a, Arbitrary a) => [Law a]
 additiveLawsFail =
   [ ( "associative: (a + b) + c = a + (b + c)"
@@ -156,8 +194,20 @@
   , ("commutative: a * b == b * a", Binary (\a b -> a * b == b * a))
   ]
 
-multiplicativeGroupLaws :: (Epsilon a, Eq a, MultiplicativeGroup a) => [Law a]
+multiplicativeGroupLaws :: (Eq a, AdditiveUnital a, MultiplicativeGroup a) => [Law a]
 multiplicativeGroupLaws =
+  [ ( "divide: a == zero || a / a == one"
+    , Unary (\a -> a == zero || (a / a) == one))
+  , ( "recip divide: recip a == one / a"
+    , Unary (\a -> a == zero || recip a == one / a))
+  , ( "recip left: a == zero || recip a * a == one"
+    , Unary (\a -> a == zero || recip a * a == one))
+  , ( "recip right: a == zero || a * recip a == one"
+    , Unary (\a -> a == zero || a * recip a == one))
+  ]
+ 
+multiplicativeGroupLaws_ :: (Epsilon a, MultiplicativeGroup a) => [Law a]
+multiplicativeGroupLaws_ =
   [ ( "divide: a == zero || a / a ≈ one"
     , Unary (\a -> a == zero || (a / a) ≈ one))
   , ( "recip divide: recip a == one / a"
@@ -182,7 +232,7 @@
   ]
 
 distributionLawsFail ::
-     (Show a, Arbitrary a, Epsilon a, Eq a, Distribution a) => [Law a]
+     (Show a, Arbitrary a, Epsilon a, Distribution a) => [Law a]
 distributionLawsFail =
   [ ( "left annihilation: a * zero == zero"
     , Unary (\a -> a `times` zero == zero))
@@ -204,70 +254,136 @@
   , ("fromIntegral a = a", Unary (\a -> fromIntegral a == a))
   ]
 
+-- rational
+rationalLaws :: (Eq a, FromRatio a, ToRatio a) => [Law a]
+rationalLaws =
+  [ ("fromRational a = a", Unary (\a -> fromRational a == a))
+  ]
+
 -- metric
 signedLaws :: (Eq a, Signed a) => [Law a]
 signedLaws = [("sign a * abs a == a", Unary (\a -> sign a `times` abs a == a))]
 
-metricFloatLaws :: () => [Law Float]
-metricFloatLaws =
-  [ ("positive", Binary (\a b -> (distance a b :: Float) >= zero))
-  , ("zero if equal", Unary (\a -> (distance a a :: Float) == zero))
-  , ( "associative"
-    , Binary (\a b -> (distance a b :: Float) ≈ (distance b a :: Float)))
-  , ( "triangle rule - sum of distances > distance"
-    , Ternary
-        (\a b c ->
-           (abs a > 10.0) ||
-           (abs b > 10.0) ||
-           (abs c > 10.0) ||
+normedLaws :: forall a b. (Ord b, AdditiveUnital a, AdditiveUnital b, MultiplicativeUnital b, Normed a b) =>
+  [Law2 a b]
+normedLaws =
+  [ ("positive", Binary11 (\a p -> p < (one :: b) || (normLp p a :: b) >= (zero :: b)))
+  , ("preserves zero"
+    , Binary11 (\_ p -> p < (one :: b) || (normLp p (zero :: a) :: b) == (zero :: b)) )
+  ]
+
+normedBoundedLaws :: forall a b. (Eq a, Bounded a, Ord b, AdditiveUnital a, AdditiveUnital b, MultiplicativeUnital b, Normed a b) =>
+  [Law2 a b]
+normedBoundedLaws =
+  [ ("positive or non-minBound", Binary11 (\a p -> a == minBound || p < (one :: b) || (normLp p a :: b) >= (zero :: b)))
+  , ("preserves zero"
+    , Binary11 (\_ p -> p < (one :: b) || (normLp p (zero :: a) :: b) == (zero :: b)) )
+  ]
+
+metricIntegralLaws :: forall a b. (FromInteger b, Ord b, Signed b, Epsilon b, Metric a b) =>
+  [Law2 a b]
+metricIntegralLaws =
+  [ ("Lp: positive",
+     Ternary21 (\a b p -> p < one || distanceLp p a b >= zero))
+  , ("Lp: zero if equal"
+    , Binary11 (\a p -> p < one || distanceLp p a a == zero))
+  , ( "Lp: associative"
+    , Ternary21 (\a b p ->
+                  p < one ||
+                  p > (smallIntegralPower :: b) ||
+                 distanceLp p a b ≈ distanceLp p b a))
+  , ( "Lp: triangle rule - sum of distances > distance"
+    , Quad31
+        (\a b c p ->
+           (p < one) ||
            not
              (veryNegative
-                (distance a c + distance b c - (distance a b :: Float))) &&
+                (distanceLp p a c + distanceLp p b c - distanceLp p a b)) &&
            not
              (veryNegative
-                (distance a b + distance b c - (distance a c :: Float))) &&
+                (distanceLp p a b + distanceLp p b c - distanceLp p a c)) &&
            not
              (veryNegative
-                (distance a b + distance a c - (distance b c :: Float)))))
+                (distanceLp p a b + distanceLp p a c - distanceLp p b c))))
   ]
 
-metricComplexFloatLaws :: () => [Law (Complex Float)]
-metricComplexFloatLaws =
-  [ ("positive", Binary (\a b -> (distance a b :: Float) >= zero))
-  , ("zero if equal", Unary (\a -> (distance a a :: Float) == zero))
-  , ( "associative"
-    , Binary (\a b -> (distance a b :: Float) ≈ (distance b a :: Float)))
-  , ( "triangle rule - sum of distances > distance"
-    , Ternary
-        (\a b c ->
-           (size a > (10.0 :: Float)) ||
-           (size b > (10.0 :: Float)) ||
-           (size c > (10.0 :: Float)) ||
+-- triangle rule doesn't apply to bounded Integrals
+metricIntegralBoundedLaws :: forall a b. (FromInteger b, Bounded b, Ord b, Signed b, Epsilon b, Metric a b) =>
+  [Law2 a b]
+metricIntegralBoundedLaws =
+  [ ("Lp: positive",
+     Ternary21 (\a b p -> p < one || distanceLp p a b >= zero || distanceLp p a b == minBound))
+  , ("Lp: zero if equal"
+    , Binary11 (\a p -> p < one || distanceLp p a a == zero))
+  , ( "Lp: associative"
+    , Ternary21 (\a b p ->
+                  p < one ||
+                  p > (smallIntegralPower :: b) ||
+                 distanceLp p a b ≈ distanceLp p b a))
+  ]
+
+
+metricRationalLaws :: forall a b. (FromRatio b, Ord b, Signed b, Epsilon b, Metric a b, Normed a b) =>
+  [Law2 a b]
+metricRationalLaws =
+  [ ("Lp: positive",
+     Ternary21 (\a b p -> p < one || distanceLp p a b >= zero))
+  , ("Lp: zero if equal"
+    , Binary11 (\a p -> p < one || distanceLp p a a == zero))
+  , ( "Lp: associative"
+    , Ternary21 (\a b p ->
+                  p < one ||
+                  p > (smallRationalPower :: b) ||
+                 distanceLp p a b ≈ distanceLp p b a))
+  , ( "Lp: triangle rule - sum of distances > distance"
+    , Quad31
+        (\a b c p ->
+           (p < one) ||
+           (normL1 a > (smallRational :: b)) ||
+           (normL1 b > (smallRational :: b)) ||
+           (normL1 c > (smallRational :: b)) ||
            not
              (veryNegative
-                (distance a c + distance b c - (distance a b :: Float))) &&
+                (distanceLp p a c + distanceLp p b c - distanceLp p a b)) &&
            not
              (veryNegative
-                (distance a b + distance b c - (distance a c :: Float))) &&
+                (distanceLp p a b + distanceLp p b c - distanceLp p a c)) &&
            not
              (veryNegative
-                (distance a b + distance a c - (distance b c :: Float)))))
+                (distanceLp p a b + distanceLp p a c - distanceLp p b c))))
   ]
 
--- field
-boundedFieldFloatLaws :: [Law Float]
-boundedFieldFloatLaws =
-  [ ( "infinity laws"
+-- bounded fields
+upperBoundedFieldLaws :: forall a. (Eq a, UpperBoundedField a) => [Law a]
+upperBoundedFieldLaws =
+  [ ( "upper bounded field (infinity) laws"
     , Unary
         (\a ->
-           ((one :: Float) / zero + infinity == infinity) &&
+           ((one ::a) / zero + infinity == infinity) &&
            (infinity + a == infinity) &&
-           isNaN ((infinity :: Float) - infinity) &&
-           isNaN ((infinity :: Float) / infinity) &&
-           isNaN (nan + a) && (zero :: Float) / zero /= nan))
+           isNaN ((infinity :: a) / infinity) &&
+           isNaN (nan + a) &&
+           (zero :: a) / zero /= nan))
   ]
 
-quotientFieldLaws :: (Ord a, Field a, QuotientField a, FromInteger a) => [Law a]
+lowerBoundedFieldLaws :: forall a. (Eq a, UpperBoundedField a, LowerBoundedField a) => [Law a]
+lowerBoundedFieldLaws =
+  [ ( "lower bounded field (negative infinity) laws"
+    , Unary
+        (\a ->
+           (negate (one ::a) / zero == negInfinity) &&
+           ((negInfinity :: a) + negInfinity == negInfinity) &&
+           (negInfinity + a == negInfinity) &&
+           isNaN ((infinity :: a) - infinity) &&
+           isNaN ((negInfinity :: a) - negInfinity) &&
+           isNaN ((negInfinity :: a) / negInfinity) &&
+           isNaN (nan + a) && (zero :: a) / zero /= nan))
+  ]
+
+
+
+
+quotientFieldLaws :: (Field a, QuotientField a, FromInteger a) => [Law a]
 quotientFieldLaws =
   [ ( "a - one < floor a <= a <= ceiling a < a + one"
     , Unary
@@ -280,87 +396,54 @@
     , Unary (\a -> round a == floor (a + one / (one + one))))
   ]
 
-expFieldLaws ::
-     (ExpField a, Signed a, Epsilon a, Fractional a, Ord a) => [Law a]
+expFieldLaws :: forall a b.
+     (FromInteger b, AdditiveUnital b, ExpField a, Normed a b, Epsilon a, Ord a, Ord b) => [Law2 a b]
 expFieldLaws =
   [ ( "sqrt . (**(one+one)) ≈ id"
-    , Unary
+    , Unary10
         (\a ->
-           not (veryPositive a) ||
-           (a > 10.0) ||
+           not (a > (zero :: a)) ||
+           (normL1 a > (10 :: b)) ||
            (sqrt . (** (one + one)) $ a) ≈ a &&
            ((** (one + one)) . sqrt $ a) ≈ a))
   , ( "log . exp ≈ id"
-    , Unary
+    , Unary10
         (\a ->
-           not (veryPositive a) ||
-           (a > 10.0) || (log . exp $ a) ≈ a && (exp . log $ a) ≈ a))
+           not (a > (zero :: a)) ||
+           (normL1 a > (10 :: b)) || (log . exp $ a) ≈ a && (exp . log $ a) ≈ a))
   , ( "for +ive b, a != 0,1: a ** logBase a b ≈ b"
-    , Binary
+    , Binary20
         (\a b ->
-           (not (veryPositive b) ||
-            not (nearZero (a - zero)) ||
-            (a == one) ||
-            (a == zero && nearZero (logBase a b)) || (a ** logBase a b ≈ b))))
-  ]
-
-expFieldComplexLooseLaws :: Float -> [Law (Complex Float)]
-expFieldComplexLooseLaws _ =
-  [ ( "sqrt . (**(one+one)) ≈ id test contains a stack overflow"
-    , Unary (const True))
-  , ("log . exp test contains a stack overflow", Unary (const True))
-  , ( "for +ive b, a != 0,1: a ** logBase a b ≈ b"
-    , Binary
-        (\a b@(rb :+ ib) ->
-           (not (rb > zero && ib > zero) ||
+           (not (normL1 b > (zero :: b)) ||
             not (nearZero (a - zero)) ||
             (a == one) ||
             (a == zero && nearZero (logBase a b)) || (a ** logBase a b ≈ b))))
   ]
 
-metricNaperianFloatLaws :: (Metric (r Float) Float) => [Law (r Float)]
-metricNaperianFloatLaws =
-  [ ("positive", Binary (\a b -> distance a b >= (zero :: Float)))
-  , ("zero if equal", Unary (\a -> distance a a == (zero :: Float)))
-  , ("associative", Binary (\a b -> distance a b ≈ (distance b a :: Float)))
-  , ( "triangle rule - sum of distances > distance"
-    , Ternary
-        (\a b c ->
-           not
-             (veryNegative
-                (distance a c + distance b c - (distance a b :: Float))) &&
-           not
-             (veryNegative
-                (distance a b + distance b c - (distance a c :: Float))) &&
-           not
-             (veryNegative
-                (distance a b + distance a c - (distance b c :: Float)))))
-  ]
-
-expFieldNaperianLaws ::
+expFieldContainerLaws ::
      ( ExpField (r a)
      , Foldable r
      , ExpField a
      , Epsilon a
      , Signed a
+     , FromRatio a
      , Epsilon (r a)
-     , Fractional a
      , Ord a
      )
   => [Law (r a)]
-expFieldNaperianLaws =
+expFieldContainerLaws =
   [ ( "sqrt . (**2) ≈ id"
     , Unary
         (\a ->
            not (all veryPositive a) ||
-           any (> 10.0) a ||
+           any (> smallRational) a ||
            (sqrt . (** (one + one)) $ a) ≈ a &&
            ((** (one + one)) . sqrt $ a) ≈ a))
   , ( "log . exp ≈ id"
     , Unary
         (\a ->
            not (all veryPositive a) ||
-           any (> 10.0) a || (log . exp $ a) ≈ a && (exp . log $ a) ≈ a))
+           any (> smallRational) a || (log . exp $ a) ≈ a && (exp . log $ a) ≈ a))
   , ( "for +ive b, a != 0,1: a ** logBase a b ≈ b"
     , Binary
         (\a b ->
@@ -373,91 +456,99 @@
 
 -- module
 additiveModuleLaws ::
-     (Eq (r a), Epsilon a, Epsilon (r a), AdditiveModule r a) => [Law2 (r a) a]
+     (Epsilon a, Epsilon (r a), AdditiveModule r a) => [Law2 (r a) a]
 additiveModuleLaws =
   [ ( "additive module associative: (a + b) .+ c ≈ a + (b .+ c)"
-    , Ternary2 (\a b c -> (a + b) .+ c ≈ a + (b .+ c)))
+    , Ternary21 (\a b c -> (a + b) .+ c ≈ a + (b .+ c)))
   , ( "additive module commutative: (a + b) .+ c ≈ (a .+ c) + b"
-    , Ternary2 (\a b c -> (a + b) .+ c ≈ (a .+ c) + b))
-  , ("additive module unital: a .+ zero == a", Unary2 (\a -> a .+ zero == a))
+    , Ternary21 (\a b c -> (a + b) .+ c ≈ (a .+ c) + b))
+  , ("additive module unital: a .+ zero == a", Unary10 (\a -> a .+ zero == a))
   , ( "module additive equivalence: a .+ b ≈ b +. a"
-    , Binary2 (\a b -> a .+ b ≈ b +. a))
+    , Binary11 (\a b -> a .+ b ≈ b +. a))
   ]
 
 additiveGroupModuleLaws ::
-     (Eq (r a), Epsilon a, Epsilon (r a), AdditiveGroupModule r a)
+     (Epsilon a, Epsilon (r a), AdditiveGroupModule r a)
   => [Law2 (r a) a]
 additiveGroupModuleLaws =
   [ ( "additive group module associative: (a + b) .- c ≈ a + (b .- c)"
-    , Ternary2 (\a b c -> (a + b) .- c ≈ a + (b .- c)))
+    , Ternary21 (\a b c -> (a + b) .- c ≈ a + (b .- c)))
   , ( "additive group module commutative: (a + b) .- c ≈ (a .- c) + b"
-    , Ternary2 (\a b c -> (a + b) .- c ≈ (a .- c) + b))
+    , Ternary21 (\a b c -> (a + b) .- c ≈ (a .- c) + b))
   , ( "additive group module unital: a .- zero == a"
-    , Unary2 (\a -> a .- zero == a))
+    , Unary10 (\a -> a .- zero == a))
   , ( "module additive group equivalence: a .- b ≈ negate b +. a"
-    , Binary2 (\a b -> a .- b ≈ negate b +. a))
+    , Binary11 (\a b -> a .- b ≈ negate b +. a))
   ]
 
 multiplicativeModuleLaws ::
-     (Eq (r a), Epsilon a, Epsilon (r a), MultiplicativeModule r a)
+     (Epsilon a, Epsilon (r a), MultiplicativeModule r a)
   => [Law2 (r a) a]
 multiplicativeModuleLaws =
   [ ( "multiplicative module unital: a .* one == a"
-    , Unary2 (\a -> a .* one == a))
+    , Unary10 (\a -> a .* one == a))
   , ( "module right distribution: (a + b) .* c ≈ (a .* c) + (b .* c)"
-    , Ternary2 (\a b c -> (a + b) .* c ≈ (a .* c) + (b .* c)))
+    , Ternary21 (\a b c -> (a + b) .* c ≈ (a .* c) + (b .* c)))
   , ( "module left distribution: c *. (a + b) ≈ (c *. a) + (c *. b)"
-    , Ternary2 (\a b c -> c *. (a + b) ≈ (c *. a) + (c *. b)))
-  , ("annihilation: a .* zero == zero", Unary2 (\a -> a .* zero == zero))
+    , Ternary21 (\a b c -> c *. (a + b) ≈ (c *. a) + (c *. b)))
+  , ("annihilation: a .* zero == zero", Unary10 (\a -> a .* zero == zero))
   , ( "module multiplicative equivalence: a .* b ≈ b *. a"
-    , Binary2 (\a b -> a .* b ≈ b *. a))
+    , Binary11 (\a b -> a .* b ≈ b *. a))
   ]
 
 multiplicativeGroupModuleLawsFail ::
-     ( Eq a
-     , Eq (r a)
-     , Epsilon a
+     ( Epsilon a
      , Epsilon (r a)
      , MultiplicativeGroupModule r a
      )
   => [Law2 (r a) a]
 multiplicativeGroupModuleLawsFail =
   [ ( "multiplicative group module unital: a ./ one == a"
-    , Unary2 (\a -> nearZero a || a ./ one == a))
+    , Unary10 (\a -> nearZero a || a ./ one == a))
   , ( "module multiplicative group equivalence: a ./ b ≈ recip b *. a"
-    , Binary2 (\a b -> b == zero || a ./ b ≈ recip b *. a))
+    , Binary11 (\a b -> b == zero || a ./ b ≈ recip b *. a))
   ]
 
 banachLaws ::
-     ( Ord a
-     , Fractional a
-     , Signed a
-     , Foldable r
-     , Eq (r a)
+     ( Foldable r
      , Epsilon (r a)
      , Banach r a
      , Singleton r
+     , Signed a
+     , FromRatio a
+     , Ord a
      )
-  => [Law2 (r a) b]
+  => [Law2 (r a) a]
 banachLaws =
-  [ ( "normalize a .* size a ≈ one"
-    , Unary2
+  [ ( "L1: normalize a .* norm a ≈ one"
+    , Unary10
         (\a ->
            a == singleton zero ||
-           (any ((> 10.0) . abs) a || (normalize a .* size a) ≈ a)))
+           (any ((> smallRational) . abs) a || (normalizeL1 a .* normL1 a) ≈ a)))
+    , ( "L2: normalize a .* norm a ≈ one"
+    , Unary10
+        (\a ->
+           a == singleton zero ||
+           (any ((> smallRational) . abs) a || (normalizeL2 a .* normL2 a) ≈ a)))
+{-
+    , ( "Lp: normalizeLp a p .* normLp a p ≈ one"
+    , Binary11
+        (\a p ->
+           a == singleton zero ||
+           (any ((> smallRational) . normL1) a || (normalizeLp p a .* normLp p a) ≈ a)))
+-}
   ]
 
 hilbertLaws ::
-    ( Eq a
-    , MultiplicativeModule r a
+    ( MultiplicativeModule r a
     , Epsilon a
     , Epsilon (r a)
     , Hilbert r a)
   => [Law2 (r a) a]
 hilbertLaws =
-  [ ("commutative a <.> b ≈ b <.> a", Ternary2 (\a b _ -> a <.> b ≈ b <.> a))
+  [ ("commutative a <.> b ≈ b <.> a", Ternary21 (\a b _ -> a <.> b ≈ b <.> a))
   , ( "distributive over addition a <.> (b + c) == a <.> b + a <.> c"
-    , Ternary2'' (\a b c -> a <.> (b + c) ≈ a <.> b + a <.> c))
+    , Ternary30 (\a b c -> a <.> (b + c) ≈ a <.> b + a <.> c))
   , ( "bilinear a <.> (s *. b + c) == s * (a <.> b) + a <.> c"
     , Quad31 (\a b c s -> a <.> (s *. b + c) == s * (a <.> b) + a <.> c))
   , ( "scalar multiplication (s0 *. a) <.> (s1 *. b) == s0 * s1 * (a <.> b)"
@@ -473,17 +564,17 @@
   => [Law2 (r a) a]
 tensorProductLaws =
   [ ( "left distribution over addition a><b + c><b == (a+c) >< b"
-    , Ternary2'' (\a b c -> a >< b + c >< b == (a + c) >< b))
+    , Ternary30 (\a b c -> a >< b + c >< b == (a + c) >< b))
   , ( "right distribution over addition a><b + a><c == a >< (b+c)"
-    , Ternary2'' (\a b c -> a >< b + a >< c == a >< (b + c)))
+    , Ternary30 (\a b c -> a >< b + a >< c == a >< (b + c)))
   -- , ( "left module tensor correspondance a *. (b><c) == (a><b) .* c"
-  --   , Ternary2'' (\a b c -> a *. (b><c) == (a><b) .* c))
+  --   , Ternary30 (\a b c -> a *. (b><c) == (a><b) .* c))
   -- , ( "right module tensor correspondance (a><b) .* c == a *. (b><c)"
-  --   , Ternary2'' (\a b c -> (a><b) .* c == a *. (b><c)))
+  --   , Ternary30 (\a b c -> (a><b) .* c == a *. (b><c)))
   ]
 
 -- basis
-additiveBasisLaws :: (Eq (r a), Epsilon (r a), AdditiveBasis r a) => [Law (r a)]
+additiveBasisLaws :: (Epsilon (r a), AdditiveBasis r a) => [Law (r a)]
 additiveBasisLaws =
   [ ( "associative: (a .+. b) .+. c ≈ a .+. (b .+. c)"
     , Ternary (\a b c -> (a .+. b) .+. c ≈ a .+. (b .+. c)))
@@ -509,8 +600,7 @@
   ]
 
 multiplicativeGroupBasisLaws ::
-     ( Eq (r a)
-     , Epsilon a
+     ( Epsilon a
      , Epsilon (r a)
      , Singleton r
      , MultiplicativeGroupBasis r a
@@ -522,7 +612,7 @@
   ]
 
 -- | semiring
-semiringLaws :: (Eq a, Semiring a) => [Law a]
+semiringLaws :: (Epsilon a, Semiring a) => [Law a]
 semiringLaws = additiveLaws <> distributionLaws <>
     [ ( "associative: (a * b) * c = a * (b * c)"
     , Ternary (\a b c -> (a `times` b) `times` c == a `times` (b `times` c)))
@@ -531,13 +621,38 @@
     ]
 
 -- | ring
-ringLaws :: (Eq a, Ring a) => [Law a]
+ringLaws :: (Epsilon a, Ring a) => [Law a]
 ringLaws = semiringLaws <> additiveGroupLaws
 
 -- | starsemiring
-starSemiringLaws :: (Eq a, StarSemiring a) => [Law a]
+starSemiringLaws :: (Epsilon a, StarSemiring a) => [Law a]
 starSemiringLaws = semiringLaws <>
     [ ( "star law: star a == one + a `times` star a"
     , Unary (\a -> star a == one + a `times` star a))
     ]
+
+-- | involutive ring
+involutiveRingLaws :: forall a. (Eq a, MultiplicativeUnital a,InvolutiveRing a) => [Law a]
+involutiveRingLaws =
+    [ ( "adjoint plus law: adj (a + b) ==> adj a + adj b"
+    , Binary (\a b -> adj (a `plus` b) == adj a `plus` adj b))
+    , ( "adjoint times law: adj (a * b) ==> adj b * adj a"
+    , Binary (\a b -> adj (a `times` b) == adj b `times` adj a))
+    , ( "adjoint multiplicative unit law: adj one ==> one"
+    , Nonary (adj (one :: a) == one))
+    , ( "adjoint own inverse law: adj (adj a) ==> a"
+    , Unary (\a -> adj (adj a) == a))
+    ]
+
+
+-- integrals are the law groups that apply to Integral-like numbers
+integralsLaws :: (Eq a, AdditiveGroup a, Integral a, Signed a, ToInteger a, FromInteger a, Multiplicative a) => [Law a]
+integralsLaws =
+  additiveLaws <>
+  additiveGroupLaws <>
+  multiplicativeLaws <>
+  distributionLaws <>
+  integralLaws <>
+  signedLaws
+
 
diff --git a/src/NumHask/Prelude.hs b/src/NumHask/Prelude.hs
--- a/src/NumHask/Prelude.hs
+++ b/src/NumHask/Prelude.hs
@@ -10,6 +10,10 @@
   , (<>)
   , Semigroup
 #endif
+    -- RebindableSyntax takes fromString away so we need to put it back in
+  , fromString
+  , Complex(..)
+  , Natural(..)
     -- * Algebraic Heirarchy
     -- $instances
   , module NumHask.Algebra.Additive
@@ -21,6 +25,7 @@
   , module NumHask.Algebra.Metric
   , module NumHask.Algebra.Module
   , module NumHask.Algebra.Multiplicative
+  , module NumHask.Algebra.Rational
   , module NumHask.Algebra.Ring
   , module NumHask.Algebra.Singleton
 
@@ -28,23 +33,26 @@
 
 #if MIN_VERSION_base(4,11,0)
 import Protolude
-       hiding (Bounded(..), Integral(..), Rep, Semiring(..), (*), (**),
+       hiding (Integral(..), Rep, Semiring(..), (*), (**),
                (+), (-), (/), (^), (^^), abs, acos, acosh, asin, asinh, atan,
                atan2, atanh, ceiling, cos, cosh, exp, floor, fromInteger,
-               fromIntegral, infinity, isNaN, log, logBase, negate, pi, product,
-               recip, round, sin, sinh, sqrt, sum, tan, tanh, toInteger, trans,
-               zero)
+               fromIntegral, even, odd, infinity, isNaN, log, logBase, negate, pi, product,
+               properFraction, recip, round, sin, sinh, sqrt, sum, tan, tanh, toInteger, trans,
+               zero, fromRational, Ratio(..), Rational, reduce, gcd)
 #else
 import Protolude
-       hiding (Bounded(..), Integral(..), Rep, Semiring(..), (*), (**),
+       hiding (Integral(..), Rep, Semiring(..), (*), (**),
                (+), (-), (/), (^), (^^), abs, acos, acosh, asin, asinh, atan,
                atan2, atanh, ceiling, cos, cosh, exp, floor, fromInteger,
-               fromIntegral, infinity, isNaN, log, logBase, negate, pi, product,
-               recip, round, sin, sinh, sqrt, sum, tan, tanh, toInteger, trans,
-               zero, (<>), Semgroup)
+               fromIntegral, even, odd, infinity, isNaN, log, logBase, negate, pi, product,
+               properFraction, recip, round, sin, sinh, sqrt, sum, tan, tanh, toInteger, trans,
+               zero, fromRational, Ratio(..), Rational, reduce, gcd, (<>), Semigroup)
 import Data.Semigroup ((<>), Semigroup)
 #endif
 
+import Data.String
+import GHC.Natural(Natural(..))
+
 import NumHask.Algebra.Additive
 import NumHask.Algebra.Basis
 import NumHask.Algebra.Distribution
@@ -54,6 +62,7 @@
 import NumHask.Algebra.Metric
 import NumHask.Algebra.Module
 import NumHask.Algebra.Multiplicative
+import NumHask.Algebra.Rational
 import NumHask.Algebra.Ring
 import NumHask.Algebra.Singleton
 
@@ -63,5 +72,5 @@
 -- $instances
 -- Re-defines the numeric tower.
 --
--- Instances for 'Int', 'Integer', 'Float', 'Double', 'Bool' and 'Complex' are supplied.
+-- Instances for 'Int', 'Integer', 'Float', 'Double', 'Bool', 'Complex' and 'Natural'are supplied.
 --
diff --git a/stack.yaml b/stack.yaml
--- a/stack.yaml
+++ b/stack.yaml
@@ -1,4 +1,4 @@
-resolver: nightly-2018-04-04
+resolver: nightly-2018-05-06
 
 packages:
   - .
diff --git a/test/test.hs b/test/test.hs
--- a/test/test.hs
+++ b/test/test.hs
@@ -1,4 +1,7 @@
+{-# LANGUAGE TypeSynonymInstances #-}
+{-# LANGUAGE FlexibleInstances #-}
 {-# OPTIONS_GHC -Wall #-}
+{-# OPTIONS_GHC -fno-warn-orphans #-}
 
 -- | testing IEEE numbers is a special kind of hell, and one that I reserve for days when I can hardly think, so please forgive the horrible hackery contained within this file.
 --
@@ -6,12 +9,22 @@
 module Main where
 
 import NumHask.Prelude
+import GHC.Natural (Natural(..))
 import NumHask.Laws
 
 import Test.DocTest
 import Test.Tasty
        (TestTree, defaultMain, testGroup)
 
+import Test.QuickCheck.Arbitrary
+import Test.QuickCheck.Gen
+
+instance Arbitrary Natural where
+  arbitrary = fromInteger . abs <$> arbitrary
+
+instance Arbitrary Rational where
+  arbitrary = reduce <$> (fromInteger <$> arbitrary) <*> (fromInteger <$> arbitrary `suchThat` (>zero))
+
 main :: IO ()
 main = do
   doctest ["src/NumHask/Examples.hs"]
@@ -22,9 +35,21 @@
   testGroup
     "NumHask"
     [ testsInt
+    , testsInt8
+    , testsInt16
+    , testsInt32
+    , testsInt64
+    , testsWord
+    , testsWord8
+    , testsWord16
+    , testsWord32
+    , testsWord64
+    , testsNatural
     , testsFloat
+    , testsDouble
     , testsBool
     , testsComplexFloat
+    , testsRational
     ]
 
 testsInt :: TestTree
@@ -38,8 +63,158 @@
     , testGroup "Distribution" $ testLawOf ([] :: [Int]) <$> distributionLaws
     , testGroup "Integral" $ testLawOf ([] :: [Int]) <$> integralLaws
     , testGroup "Signed" $ testLawOf ([] :: [Int]) <$> signedLaws
+    , testGroup "Metric" $ testLawOf2 ([] :: [(Int, Int)]) <$>
+      metricIntegralLaws
+    , testGroup "Normed or maxBound" $ testLawOf2 ([] :: [(Int, Int)]) <$> normedBoundedLaws
     ]
 
+testsInteger :: TestTree
+testsInteger =
+  testGroup
+    "Integer"
+    [ testGroup "Integrals" $ testLawOf ([] :: [Integer]) <$> integralsLaws
+    , testGroup "Metric" $ testLawOf2 ([] :: [(Integer, Integer)]) <$>
+      metricIntegralLaws
+    , testGroup "Normed" $ testLawOf2 ([] :: [(Integer, Integer)]) <$> normedLaws
+    ]
+
+testsInt8 :: TestTree
+testsInt8 =
+  testGroup
+    "Int8"
+    [ testGroup "Integrals" $ testLawOf ([] :: [Int8]) <$> integralsLaws
+    , testGroup "Metric" $ testLawOf2 ([] :: [(Int8, Int8)]) <$>
+      metricIntegralBoundedLaws
+    , testGroup "Normed or maxBound" $ testLawOf2 ([] :: [(Int8, Int8)]) <$>
+      normedBoundedLaws
+    ]
+
+testsInt16 :: TestTree
+testsInt16 =
+  testGroup
+    "Int16"
+    [ testGroup "Integrals" $ testLawOf ([] :: [Int16]) <$> integralsLaws
+    , testGroup "Metric" $ testLawOf2 ([] :: [(Int16, Int16)]) <$>
+      metricIntegralBoundedLaws
+    , testGroup "Normed or maxBound" $ testLawOf2 ([] :: [(Int16, Int16)]) <$>
+      normedBoundedLaws
+    ]
+
+testsInt32 :: TestTree
+testsInt32 =
+  testGroup
+    "Int32"
+    [ testGroup "Integrals" $ testLawOf ([] :: [Int32]) <$> integralsLaws
+    , testGroup "Metric" $ testLawOf2 ([] :: [(Int32, Int32)]) <$>
+      metricIntegralBoundedLaws
+    , testGroup "Normed or maxBound" $ testLawOf2 ([] :: [(Int32, Int32)]) <$>
+      normedBoundedLaws
+    ]
+
+testsInt64 :: TestTree
+testsInt64 =
+  testGroup
+    "Int64"
+    [ testGroup "Integrals" $ testLawOf ([] :: [Int64]) <$> integralsLaws
+    , testGroup "Metric" $ testLawOf2 ([] :: [(Int64, Int64)]) <$>
+      metricIntegralBoundedLaws
+    , testGroup "Normed or maxBound" $ testLawOf2 ([] :: [(Int64, Int64)]) <$>
+      normedBoundedLaws
+    ]
+
+testsWord :: TestTree
+testsWord =
+  testGroup
+    "Word"
+    [ testGroup "Additive" $ testLawOf ([] :: [Word]) <$> additiveLaws
+    , testGroup "Multiplicative" $
+      testLawOf ([] :: [Word]) <$> multiplicativeLaws
+    , testGroup "Distribution" $ testLawOf ([] :: [Word]) <$> distributionLaws
+    , testGroup "Integral" $ testLawOf ([] :: [Word]) <$> integralLaws
+    , testGroup "Signed" $ testLawOf ([] :: [Word]) <$> signedLaws
+    , testGroup "Metric" $ testLawOf2 ([] :: [(Word, Word)]) <$>
+      metricIntegralBoundedLaws
+    , testGroup "Normed or maxBound" $ testLawOf2 ([] :: [(Word, Word)]) <$>
+      normedBoundedLaws
+    ]
+
+testsWord8 :: TestTree
+testsWord8 =
+  testGroup
+    "Word8"
+    [ testGroup "Additive" $ testLawOf ([] :: [Word8]) <$> additiveLaws
+    , testGroup "Multiplicative" $
+      testLawOf ([] :: [Word8]) <$> multiplicativeLaws
+    , testGroup "Distribution" $ testLawOf ([] :: [Word8]) <$> distributionLaws
+    , testGroup "Integral" $ testLawOf ([] :: [Word8]) <$> integralLaws
+    , testGroup "Signed" $ testLawOf ([] :: [Word8]) <$> signedLaws
+    , testGroup "Metric" $ testLawOf2 ([] :: [(Word8, Word8)]) <$>
+      metricIntegralBoundedLaws
+    , testGroup "Normed or maxBound" $ testLawOf2 ([] :: [(Word8, Word8)]) <$>
+      normedBoundedLaws
+    ]
+
+testsWord16 :: TestTree
+testsWord16 =
+  testGroup
+    "Word16"
+    [ testGroup "Additive" $ testLawOf ([] :: [Word16]) <$> additiveLaws
+    , testGroup "Multiplicative" $
+      testLawOf ([] :: [Word16]) <$> multiplicativeLaws
+    , testGroup "Distribution" $ testLawOf ([] :: [Word16]) <$> distributionLaws
+    , testGroup "Integral" $ testLawOf ([] :: [Word16]) <$> integralLaws
+    , testGroup "Signed" $ testLawOf ([] :: [Word16]) <$> signedLaws
+    , testGroup "Metric" $ testLawOf2 ([] :: [(Word16, Word16)]) <$>
+      metricIntegralBoundedLaws
+    , testGroup "Normed or maxBound" $ testLawOf2 ([] :: [(Word16, Word16)]) <$>
+      normedBoundedLaws
+    ]
+
+testsWord32 :: TestTree
+testsWord32 =
+  testGroup
+    "Word32"
+    [ testGroup "Additive" $ testLawOf ([] :: [Word32]) <$> additiveLaws
+    , testGroup "Multiplicative" $
+      testLawOf ([] :: [Word32]) <$> multiplicativeLaws
+    , testGroup "Distribution" $ testLawOf ([] :: [Word32]) <$> distributionLaws
+    , testGroup "Integral" $ testLawOf ([] :: [Word32]) <$> integralLaws
+    , testGroup "Signed" $ testLawOf ([] :: [Word32]) <$> signedLaws
+    , testGroup "Metric" $ testLawOf2 ([] :: [(Word32, Word32)]) <$>
+      metricIntegralBoundedLaws
+    , testGroup "Normed or maxBound" $ testLawOf2 ([] :: [(Word32, Word32)]) <$>
+      normedBoundedLaws
+    ]
+
+testsWord64 :: TestTree
+testsWord64 =
+  testGroup
+    "Word64"
+    [ testGroup "Additive" $ testLawOf ([] :: [Word64]) <$> additiveLaws
+    , testGroup "Multiplicative" $
+      testLawOf ([] :: [Word64]) <$> multiplicativeLaws
+    , testGroup "Distribution" $ testLawOf ([] :: [Word64]) <$> distributionLaws
+    , testGroup "Integral" $ testLawOf ([] :: [Word64]) <$> integralLaws
+    , testGroup "Signed" $ testLawOf ([] :: [Word64]) <$> signedLaws
+    , testGroup "Metric" $ testLawOf2 ([] :: [(Word64, Word64)]) <$>
+      metricIntegralBoundedLaws
+    , testGroup "Normed or maxBound" $ testLawOf2 ([] :: [(Word64, Word64)]) <$>
+      normedBoundedLaws
+    ]
+
+testsNatural :: TestTree
+testsNatural =
+  testGroup
+    "Natural"
+    [ testGroup "Additive" $ testLawOf ([] :: [Natural]) <$> additiveLaws
+    , testGroup "Multiplicative" $
+      testLawOf ([] :: [Natural]) <$> multiplicativeLaws
+    , testGroup "Distribution" $ testLawOf ([] :: [Natural]) <$> distributionLaws
+    , testGroup "Naturalegral" $ testLawOf ([] :: [Natural]) <$> integralLaws
+    , testGroup "Signed" $ testLawOf ([] :: [Natural]) <$> signedLaws
+    , testGroup "Normed" $ testLawOf2 ([] :: [(Natural, Natural)]) <$> normedLaws
+    ]
+
 testsFloat :: TestTree
 testsFloat =
   testGroup
@@ -51,18 +226,49 @@
     , testGroup "Multiplicative - Associative Fail" $
       testLawOf ([] :: [Float]) <$> multiplicativeLawsFail
     , testGroup "MultiplicativeGroup" $
-      testLawOf ([] :: [Float]) <$> multiplicativeGroupLaws
+      testLawOf ([] :: [Float]) <$> multiplicativeGroupLaws_
     , testGroup "Distribution - Fail" $
       testLawOf ([] :: [Float]) <$> distributionLawsFail
     , testGroup "Signed" $ testLawOf ([] :: [Float]) <$> signedLaws
-    , testGroup "Bounded Field" $
-      testLawOf ([] :: [Float]) <$> boundedFieldFloatLaws
-    , testGroup "Metric" $ testLawOf ([] :: [Float]) <$> metricFloatLaws
+    , testGroup "Normed" $ testLawOf2 ([] :: [(Float, Float)]) <$> normedLaws
+    , testGroup "Metric" $ testLawOf2 ([] :: [(Float, Float)]) <$> metricRationalLaws
+    , testGroup "Upper Bounded Field" $
+      testLawOf ([] :: [Float]) <$> upperBoundedFieldLaws
+    , testGroup "Lower Bounded Field" $
+      testLawOf ([] :: [Float]) <$> lowerBoundedFieldLaws
     , testGroup "Quotient Field" $
       testLawOf ([] :: [Float]) <$> quotientFieldLaws
-    , testGroup "Exponential Field" $ testLawOf ([] :: [Float]) <$> expFieldLaws
+    , testGroup "Exponential Field" $ testLawOf2 ([] :: [(Float,Float)]) <$> expFieldLaws
+    , testGroup "Rational" $ testLawOf ([] :: [Float]) <$> rationalLaws
     ]
 
+testsDouble :: TestTree
+testsDouble =
+  testGroup
+    "Double"
+    [ testGroup "Additive - Associative Fail" $
+      testLawOf ([] :: [Double]) <$> additiveLawsFail
+    , testGroup "Additive Group" $
+      testLawOf ([] :: [Double]) <$> additiveGroupLaws
+    , testGroup "Multiplicative - Associative Fail" $
+      testLawOf ([] :: [Double]) <$> multiplicativeLawsFail
+    , testGroup "MultiplicativeGroup" $
+      testLawOf ([] :: [Double]) <$> multiplicativeGroupLaws_
+    , testGroup "Distribution - Fail" $
+      testLawOf ([] :: [Double]) <$> distributionLawsFail
+    , testGroup "Signed" $ testLawOf ([] :: [Double]) <$> signedLaws
+    , testGroup "Normed" $ testLawOf2 ([] :: [(Double, Double)]) <$> normedLaws
+    , testGroup "Metric" $ testLawOf2 ([] :: [(Double, Double)]) <$> metricRationalLaws
+    , testGroup "Upper Bounded Field" $
+      testLawOf ([] :: [Double]) <$> upperBoundedFieldLaws
+    , testGroup "Lower Bounded Field" $
+      testLawOf ([] :: [Double]) <$> lowerBoundedFieldLaws
+    , testGroup "Quotient Field" $
+      testLawOf ([] :: [Double]) <$> quotientFieldLaws
+    , testGroup "Exponential Field" $ testLawOf2 ([] :: [(Double,Double)]) <$> expFieldLaws
+    , testGroup "Rational" $ testLawOf ([] :: [Double]) <$> rationalLaws
+    ]
+
 testsBool :: TestTree
 testsBool =
   testGroup
@@ -85,11 +291,46 @@
     , testGroup "Multiplicative - Associative Fail" $
       testLawOf ([] :: [Complex Float]) <$> multiplicativeLawsFail
     , testGroup "MultiplicativeGroup" $
-      testLawOf ([] :: [Complex Float]) <$> multiplicativeGroupLaws
+      testLawOf ([] :: [Complex Float]) <$> multiplicativeGroupLaws_
     , testGroup "Distribution - Fail" $
       testLawOf ([] :: [Complex Float]) <$> distributionLawsFail
-    , testGroup "Exponential Field" $
-      testLawOf ([] :: [Complex Float]) <$> expFieldComplexLooseLaws 10
-    , testGroup "Metric" $
-      testLawOf ([] :: [Complex Float]) <$> metricComplexFloatLaws
+    -- , testGroup "Exponential Field" $
+    --   testLawOf2 ([] :: [(Complex Float, Float)]) <$> expFieldLaws 
+    , testGroup "Normed" $ testLawOf2 ([] :: [(Complex Float, Float)]) <$>
+      normedLaws
+    , testGroup "Metric" $ testLawOf2 ([] :: [(Complex Float, Float)]) <$>
+      metricRationalLaws
+    , testGroup "Involutive Ring" $ testLawOf ([] :: [Complex Float]) <$>
+      involutiveRingLaws
+    ]
+
+testsRational :: TestTree
+testsRational =
+  testGroup
+    "Rational"
+    [ testGroup "Additive - Associative" $
+      testLawOf ([] :: [Rational]) <$> additiveLaws
+    , testGroup "Additive Group" $
+      testLawOf ([] :: [Rational]) <$> additiveGroupLaws
+    , testGroup "Multiplicative - Associative" $
+      testLawOf ([] :: [Rational]) <$> multiplicativeLaws
+    , testGroup "MultiplicativeGroup" $
+      testLawOf ([] :: [Rational]) <$> multiplicativeGroupLaws_
+    , testGroup "Distribution" $
+      testLawOf ([] :: [Rational]) <$> distributionLaws
+    , testGroup "Signed" $ testLawOf ([] :: [Rational]) <$> signedLaws
+    , testGroup "Normed" $ testLawOf2 ([] :: [(Rational, Rational)]) <$> normedLaws
+    , testGroup "Metric" $ testLawOf2 ([] :: [(Rational, Rational)]) <$> metricRationalLaws
+    , testGroup "Rational" $ testLawOf ([] :: [Rational]) <$> rationalLaws
+
+    -- fixme: rounding and infinities need work
+{-
+    , testGroup "Quotient Field" $
+      testLawOf ([] :: [Rational]) <$> quotientFieldLaws
+    , testGroup "Upper Bounded Field" $
+      testLawOf ([] :: [Rational]) <$> upperBoundedFieldLaws
+    , testGroup "Lower Bounded Field" $
+      testLawOf ([] :: [Rational]) <$> lowerBoundedFieldLaws
+
+-}
     ]
