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.5.1
+version:        0.1.0.0
 synopsis:       A numeric prelude
 description:    A numeric prelude, combining protolude and numhask.
 category:       mathematics
@@ -31,17 +31,13 @@
       -Wincomplete-uni-patterns
       -Wredundant-constraints
   build-depends:
-      QuickCheck >=2.8 && <3
-    , base >=4.7 && <4.12
+      base >=4.7 && <4.12
     , numhask >=0.2.2.0 && <0.3
     , protolude >=0.1 && <0.3
-    , tasty >= 1.0.1.1 && <1.2
-    , tasty-quickcheck >= 0.9.2 && <1.0
   exposed-modules:
       NumHask.Prelude
       NumHask.Error
       NumHask.Examples
-      NumHask.Laws
   other-modules:
       Paths_numhask_prelude
   default-language: Haskell2010
@@ -53,11 +49,6 @@
       test
   default-extensions: NegativeLiterals NoImplicitPrelude OverloadedStrings UnicodeSyntax
   build-depends:
-      base >=4.7 && <5
-    , QuickCheck >=2.8 && <3
-    , doctest
+      doctest
     , numhask-prelude
-    , tasty
-  other-modules:
-      Paths_numhask_prelude
   default-language: Haskell2010
diff --git a/src/NumHask/Laws.hs b/src/NumHask/Laws.hs
deleted file mode 100644
--- a/src/NumHask/Laws.hs
+++ /dev/null
@@ -1,649 +0,0 @@
-{-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE RankNTypes #-}
-{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE RebindableSyntax #-}
-{-# OPTIONS_GHC -fno-warn-type-defaults #-}
-
-module NumHask.Laws
-  ( LawArity(..)
-  , LawArity2(..)
-  , Law
-  , Law2
-  , testLawOf
-  , testLawOf2
-  , idempotentLaws
-  , additiveLaws
-  , additiveLaws_
-  , additiveLawsFail
-  , additiveGroupLaws
-  , multiplicativeLaws
-  , multiplicativeLawsFail
-  , multiplicativeMonoidalLaws
-  , multiplicativeGroupLaws
-  , multiplicativeGroupLaws_
-  , distributionLaws
-  , distributionLawsFail
-  , integralLaws
-  , rationalLaws
-  , signedLaws
-  , normedLaws
-  , normedBoundedLaws
-  , metricIntegralLaws
-  , metricIntegralBoundedLaws
-  , metricRationalLaws
-  , upperBoundedFieldLaws
-  , lowerBoundedFieldLaws
-  , quotientFieldLaws 
-  , expFieldLaws
-  , additiveBasisLaws
-  , additiveGroupBasisLaws
-  , multiplicativeBasisLaws
-  , multiplicativeGroupBasisLaws
-  , additiveModuleLaws
-  , additiveGroupModuleLaws
-  , multiplicativeModuleLaws
-  , multiplicativeGroupModuleLawsFail
-  , 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)
-  | Binary (a -> a -> Bool)
-  | Ternary (a -> a -> a -> Bool)
-  | 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
-  = 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 Law2 a b = (TestName, LawArity2 a b)
-
-testLawOf :: (Arbitrary a, Show a) => [a] -> Law a -> TestTree
-testLawOf _ (name, Nonary f) = testProperty name f
-testLawOf _ (name, Unary f) = testProperty name f
-testLawOf _ (name, Binary f) = testProperty name f
-testLawOf _ (name, Ternary f) = testProperty name f
-testLawOf _ (name, Ornary f) = testProperty name f
-testLawOf _ (name, Failiary f) = testProperty name f
-
-testLawOf2 ::
-     (Arbitrary a, Show a, Arbitrary b, Show b)
-  => [(a, b)]
-  -> Law2 a b
-  -> TestTree
-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
-
--- idempotent
-idempotentLaws :: (Eq a, Additive a, Multiplicative a) => [Law a]
-idempotentLaws =
-  [ ("idempotent: a + a == a", Unary (\a -> a + a == a))
-  , ("idempotent: a * a == a", Unary (\a -> a * a == a))
-  ]
-
--- | additive
-additiveLaws :: (Eq a, Additive 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 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)"
-    , Failiary $ expectFailure . (\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))
-  ]
-
-additiveGroupLaws :: (Eq a, AdditiveGroup a) => [Law a]
-additiveGroupLaws =
-  [ ("minus: a - a = zero", Unary (\a -> (a - a) == zero))
-  , ("negate minus: negate a == zero - a", Unary (\a -> negate a == zero - a))
-  , ( "negate left cancel: negate a + a == zero"
-    , Unary (\a -> negate a + a == zero))
-  , ( "negate right cancel: negate a + a == zero"
-    , Unary (\a -> a + negate a == zero))
-  ]
-
--- multiplicative
-multiplicativeLaws :: (Eq a, Multiplicative a) => [Law a]
-multiplicativeLaws =
-  [ ( "associative: (a * b) * c = a * (b * c)"
-    , Ternary (\a b c -> (a * b) * c == a * (b * c)))
-  , ("left id: one * a = a", Unary (\a -> one * a == a))
-  , ("right id: a * one = a", Unary (\a -> a * one == a))
-  , ("commutative: a * b == b * a", Binary (\a b -> a * b == b * a))
-  ]
-
-multiplicativeMonoidalLaws ::
-     (Eq a, MultiplicativeUnital a) => [Law a]
-multiplicativeMonoidalLaws =
-  [ ( "associative: (a * b) * c = a * (b * c)"
-    , Ternary (\a b c -> (a `times` b) `times` c == a `times` (b `times` c)))
-  , ("left id: one `times` a = a", Unary (\a -> one `times` a == a))
-  , ("right id: a `times` one = a", Unary (\a -> a `times` one == a))
-  ]
-
-multiplicativeLawsFail ::
-     (Eq a, Show a, Arbitrary a, Multiplicative a) => [Law a]
-multiplicativeLawsFail =
-  [ ( "associative: (a * b) * c = a * (b * c)"
-    , Failiary $ expectFailure . (\a b c -> (a * b) * c == a * (b * c)))
-  , ("left id: one * a = a", Unary (\a -> one * a == a))
-  , ("right id: a * one = a", Unary (\a -> a * one == a))
-  , ("commutative: a * b == b * a", Binary (\a b -> a * b == b * 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"
-    , 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))
-  ]
-
--- distribution
-distributionLaws :: (Eq a, Distribution a) => [Law a]
-distributionLaws =
-  [ ( "left annihilation: a * zero == zero"
-    , Unary (\a -> a `times` zero == zero))
-  , ( "right annihilation: zero * a == zero"
-    , Unary (\a -> zero `times` a == zero))
-  , ( "left distributivity: a * (b + c) == a * b + a * c"
-    , Ternary (\a b c -> a `times` (b + c) == a `times` b + a `times` c))
-  , ( "right distributivity: (a + b) * c == a * c + b * c"
-    , Ternary (\a b c -> (a + b) `times` c == a `times` c + b `times` c))
-  ]
-
-distributionLawsFail ::
-     (Show a, Arbitrary a, Epsilon a, Distribution a) => [Law a]
-distributionLawsFail =
-  [ ( "left annihilation: a * zero == zero"
-    , Unary (\a -> a `times` zero == zero))
-  , ( "right annihilation: a * zero == zero"
-    , Unary (\a -> zero `times` a == zero))
-  , ( "left distributivity: a * (b + c) = a * b + a * c"
-    , Failiary $
-      expectFailure . (\a b c -> a `times` (b + c) == a `times` b + a `times` c))
-  , ( "right distributivity: (a + b) * c = a * c + b * c"
-    , Failiary $
-      expectFailure . (\a b c -> (a + b) `times` c == a `times` c + b `times` c))
-  ]
-
--- integral
-integralLaws :: (Eq a, Integral a, FromInteger a, ToInteger a) => [Law a]
-integralLaws =
-  [ ( "integral divmod: b == zero || b * (a `div` b) + (a `mod` b) == a"
-    , Binary (\a b -> b == zero || b `times` (a `div` b) + (a `mod` b) == a))
-  , ("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))]
-
-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
-                (distanceLp p a c + distanceLp p b c - distanceLp p a b)) &&
-           not
-             (veryNegative
-                (distanceLp p a b + distanceLp p b c - distanceLp p a c)) &&
-           not
-             (veryNegative
-                (distanceLp p a b + distanceLp p a c - distanceLp p b c))))
-  ]
-
--- 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
-                (distanceLp p a c + distanceLp p b c - distanceLp p a b)) &&
-           not
-             (veryNegative
-                (distanceLp p a b + distanceLp p b c - distanceLp p a c)) &&
-           not
-             (veryNegative
-                (distanceLp p a b + distanceLp p a c - distanceLp p b c))))
-  ]
-
--- bounded fields
-upperBoundedFieldLaws :: forall a. (Eq a, UpperBoundedField a) => [Law a]
-upperBoundedFieldLaws =
-  [ ( "upper bounded field (infinity) laws"
-    , Unary
-        (\a ->
-           ((one ::a) / zero + infinity == infinity) &&
-           (infinity + a == infinity) &&
-           (zero :: a) / zero /= nan))
-  ]
-
-lowerBoundedFieldLaws :: forall a. (Eq 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)))
-  ]
-
-quotientFieldLaws :: (Field a, QuotientField a Integer, FromInteger a) => [Law2 a Integer]
-quotientFieldLaws =
-  [ ( "a - one < floor a <= a <= ceiling a < a + one"
-    , Unary10
-        (\a ->
-           ((a - one) < (fromInteger (floor a))) &&
-           (fromInteger (floor a) <= a) &&
-           (a <= fromInteger (ceiling a)) &&
-           (fromInteger (ceiling a) < a + one)))
-  , ( "round a == floor (a + one/(one+one))"
-    , Unary10 (\a -> (round a :: Integer) == ((floor (a + one / (one + one))))))
-  ]
-
-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"
-    , Unary10
-        (\a ->
-           not (a > (zero :: a)) ||
-           (normL1 a > (10 :: b)) ||
-           (sqrt . (** (one + one)) $ a) ≈ a &&
-           ((** (one + one)) . sqrt $ a) ≈ a))
-  , ( "log . exp ≈ id"
-    , Unary10
-        (\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"
-    , Binary20
-        (\a b ->
-           (not (normL1 b > (zero :: b)) ||
-            not (nearZero (a - zero)) ||
-            (a == one) ||
-            (a == zero && nearZero (logBase a b)) || (a ** logBase a b ≈ b))))
-  ]
-
-expFieldContainerLaws ::
-     ( ExpField (r a)
-     , Foldable r
-     , ExpField a
-     , Epsilon a
-     , Signed a
-     , FromRatio a
-     , Epsilon (r a)
-     , Ord a
-     )
-  => [Law (r a)]
-expFieldContainerLaws =
-  [ ( "sqrt . (**2) ≈ id"
-    , Unary
-        (\a ->
-           not (all veryPositive a) ||
-           any (> smallRational) a ||
-           (sqrt . (** (one + one)) $ a) ≈ a &&
-           ((** (one + one)) . sqrt $ a) ≈ a))
-  , ( "log . exp ≈ id"
-    , Unary
-        (\a ->
-           not (all veryPositive 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 ->
-           (not (all veryPositive b) ||
-            not (all nearZero a) ||
-            all (== one) a ||
-            (all (== zero) a && all nearZero (logBase a b)) ||
-            (a ** logBase a b ≈ b))))
-  ]
-
--- module
-additiveModuleLaws ::
-     (Epsilon a, Epsilon (r a), AdditiveModule r a) => [Law2 (r a) a]
-additiveModuleLaws =
-  [ ( "additive module associative: (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"
-    , 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"
-    , Binary11 (\a b -> a .+ b ≈ b +. a))
-  ]
-
-additiveGroupModuleLaws ::
-     (Epsilon a, Epsilon (r a), AdditiveGroupModule r a)
-  => [Law2 (r a) a]
-additiveGroupModuleLaws =
-  [ ( "additive group module associative: (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"
-    , Ternary21 (\a b c -> (a + b) .- c ≈ (a .- c) + b))
-  , ( "additive group module unital: a .- zero == a"
-    , Unary10 (\a -> a .- zero == a))
-  , ( "module additive group equivalence: a .- b ≈ negate b +. a"
-    , Binary11 (\a b -> a .- b ≈ negate b +. a))
-  ]
-
-multiplicativeModuleLaws ::
-     (Epsilon a, Epsilon (r a), MultiplicativeModule r a)
-  => [Law2 (r a) a]
-multiplicativeModuleLaws =
-  [ ( "multiplicative module unital: a .* one == a"
-    , Unary10 (\a -> a .* one == a))
-  , ( "module right distribution: (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)"
-    , 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"
-    , Binary11 (\a b -> a .* b ≈ b *. a))
-  ]
-
-multiplicativeGroupModuleLawsFail ::
-     ( Epsilon a
-     , Epsilon (r a)
-     , MultiplicativeGroupModule r a
-     )
-  => [Law2 (r a) a]
-multiplicativeGroupModuleLawsFail =
-  [ ( "multiplicative group module unital: a ./ one == a"
-    , Unary10 (\a -> nearZero a || a ./ one == a))
-  , ( "module multiplicative group equivalence: a ./ b ≈ recip b *. a"
-    , Binary11 (\a b -> b == zero || a ./ b ≈ recip b *. a))
-  ]
-
-banachLaws ::
-     ( Foldable r
-     , Epsilon (r a)
-     , Banach r a
-     , Singleton r
-     , Signed a
-     , FromRatio a
-     , Ord a
-     )
-  => [Law2 (r a) a]
-banachLaws =
-  [ ( "L1: normalize a .* norm a ≈ one"
-    , Unary10
-        (\a ->
-           a == singleton zero ||
-           (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 ::
-    ( MultiplicativeModule r a
-    , Epsilon a
-    , Epsilon (r a)
-    , Hilbert r a)
-  => [Law2 (r a) a]
-hilbertLaws =
-  [ ("commutative a <.> b ≈ b <.> a", Ternary21 (\a b _ -> a <.> b ≈ b <.> a))
-  , ( "distributive over addition 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)"
-    , Quad22 (\a b s0 s1 -> (s0 *. a) <.> (s1 *. b) == s0 * s1 * (a <.> b)))
-  ]
-
-tensorProductLaws ::
-     ( Eq (r (r a))
-     , Additive (r (r a))
-     , TensorProduct (r a)
-     , Epsilon (r a)
-     )
-  => [Law2 (r a) a]
-tensorProductLaws =
-  [ ( "left distribution over addition 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)"
-    , Ternary30 (\a b c -> a >< b + a >< c == a >< (b + c)))
-  -- , ( "left module tensor correspondance 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)"
-  --   , Ternary30 (\a b c -> (a><b) .* c == a *. (b><c)))
-  ]
-
--- basis
-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)))
-  , ("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))
-  ]
-
-additiveGroupBasisLaws :: (Eq (r a), Singleton r, AdditiveGroupBasis r a) => [Law (r a)]
-additiveGroupBasisLaws =
-  [ ( "minus: a .-. a = singleton zero"
-    , Unary (\a -> (a .-. a) == singleton zero))
-  ]
-
-multiplicativeBasisLaws :: (Eq (r a), Singleton r, MultiplicativeBasis r a) => [Law (r a)]
-multiplicativeBasisLaws =
-  [ ( "associative: (a .*. b) .*. c == a .*. (b .*. c)"
-    , Ternary (\a b c -> (a .*. b) .*. c == a .*. (b .*. c)))
-  , ("left id: singleton one .*. a = a", Unary (\a -> singleton one .*. a == a))
-  , ( "right id: a .*. singleton one = a"
-    , Unary (\a -> a .*. singleton one == a))
-  , ("commutative: a .*. b == b .*. a", Binary (\a b -> a .*. b == b .*. a))
-  ]
-
-multiplicativeGroupBasisLaws ::
-     ( Epsilon a
-     , Epsilon (r a)
-     , Singleton r
-     , MultiplicativeGroupBasis r a
-     )
-  => [Law (r a)]
-multiplicativeGroupBasisLaws =
-  [ ( "basis divide: a ./. a ≈ singleton one"
-    , Unary (\a -> a == singleton zero || (a ./. a) ≈ singleton one))
-  ]
-
--- | semiring
-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)))
-    , ("left id: one * a = a", Unary (\a -> one `times` a == a))
-    , ("right id: a * one = a", Unary (\a -> a `times` one == a))
-    ]
-
--- | ring
-ringLaws :: (Epsilon a, Ring a) => [Law a]
-ringLaws = semiringLaws <> additiveGroupLaws
-
--- | starsemiring
-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
@@ -14,6 +14,7 @@
   , fromString
   , fail
   , Complex(..)
+  , module NumHask.Data.LogField
   , Natural(..)
     -- * Algebraic Heirarchy
     -- $instances
@@ -67,6 +68,7 @@
 import NumHask.Algebra.Rational
 import NumHask.Algebra.Ring
 import NumHask.Algebra.Singleton
+import NumHask.Data.LogField
 
 -- $backend
 -- NumHask imports Protolude as the prelude and replaces much of the 'Num' heirarchy in base.
diff --git a/test/test.hs b/test/test.hs
--- a/test/test.hs
+++ b/test/test.hs
@@ -1,336 +1,12 @@
 {-# 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.
---
--- This suite sometimes fails, having been hand-crafty towards balancing reasonably approximate equality versus unbounded failure (given enough trials).
 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"]
-  defaultMain tests
-
-tests :: TestTree
-tests =
-  testGroup
-    "NumHask"
-    [ testsInt
-    , testsInt8
-    , testsInt16
-    , testsInt32
-    , testsInt64
-    , testsWord
-    , testsWord8
-    , testsWord16
-    , testsWord32
-    , testsWord64
-    , testsNatural
-    , testsFloat
-    , testsDouble
-    , testsBool
-    , testsComplexFloat
-    , testsRational
-    ]
-
-testsInt :: TestTree
-testsInt =
-  testGroup
-    "Int"
-    [ testGroup "Additive" $ testLawOf ([] :: [Int]) <$> additiveLaws
-    , testGroup "Additive Group" $ testLawOf ([] :: [Int]) <$> additiveGroupLaws
-    , testGroup "Multiplicative" $
-      testLawOf ([] :: [Int]) <$> multiplicativeLaws
-    , 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
-    "Float"
-    [ testGroup "Additive - Associative Fail" $
-      testLawOf ([] :: [Float]) <$> additiveLawsFail
-    , testGroup "Additive Group" $
-      testLawOf ([] :: [Float]) <$> additiveGroupLaws
-    , testGroup "Multiplicative - Associative Fail" $
-      testLawOf ([] :: [Float]) <$> multiplicativeLawsFail
-    , testGroup "MultiplicativeGroup" $
-      testLawOf ([] :: [Float]) <$> multiplicativeGroupLaws_
-    , testGroup "Distribution - Fail" $
-      testLawOf ([] :: [Float]) <$> distributionLawsFail
-    , testGroup "Signed" $ testLawOf ([] :: [Float]) <$> signedLaws
-    , 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" $
-      testLawOf2 ([] :: [(Float,Integer)]) <$> quotientFieldLaws
-    , 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" $
-      testLawOf2 ([] :: [(Double,Integer)]) <$> quotientFieldLaws
-    , testGroup "Exponential Field" $ testLawOf2 ([] :: [(Double,Double)]) <$> expFieldLaws
-    , testGroup "Rational" $ testLawOf ([] :: [Double]) <$> rationalLaws
-    ]
-
-testsBool :: TestTree
-testsBool =
-  testGroup
-    "Bool"
-    [ testGroup "Idempotent" $ testLawOf ([] :: [Bool]) <$> idempotentLaws
-    , testGroup "Additive" $ testLawOf ([] :: [Bool]) <$> additiveLaws
-    , testGroup "Multiplicative" $
-      testLawOf ([] :: [Bool]) <$> multiplicativeLaws
-    , testGroup "Distribution" $ testLawOf ([] :: [Bool]) <$> distributionLaws
-    ]
-
-testsComplexFloat :: TestTree
-testsComplexFloat =
-  testGroup
-    "Complex Float"
-    [ testGroup "Additive - Associative Fail" $
-      testLawOf ([] :: [Complex Float]) <$> additiveLawsFail
-    , testGroup "Additive Group" $
-      testLawOf ([] :: [Complex Float]) <$> additiveGroupLaws
-    , testGroup "Multiplicative - Associative Fail" $
-      testLawOf ([] :: [Complex Float]) <$> multiplicativeLawsFail
-    , testGroup "MultiplicativeGroup" $
-      testLawOf ([] :: [Complex Float]) <$> multiplicativeGroupLaws_
-    , testGroup "Distribution - Fail" $
-      testLawOf ([] :: [Complex Float]) <$> distributionLawsFail
-    -- , 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
+main = doctest ["src/NumHask/Examples.hs"]
 
--}
-    ]
