packages feed

numhask-test (empty) → 0.1.0.0

raw patch · 6 files changed

+1107/−0 lines, 6 filesdep +QuickCheckdep +basedep +numhask-preludesetup-changed

Dependencies added: QuickCheck, base, numhask-prelude, numhask-test, tasty, tasty-quickcheck

Files

+ LICENSE view
@@ -0,0 +1,30 @@+Copyright Tony Day (c) 2016++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Tony Day nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ numhask-test.cabal view
@@ -0,0 +1,55 @@+name:           numhask-test+version:        0.1.0.0+synopsis:       Laws and tests for numhask+description:    Laws and tests for numhask.+category:       mathematics+homepage:       https://github.com/tonyday567/numhask#readme+bug-reports:    https://github.com/tonyday567/numhask/issues+author:         Tony Day+maintainer:     tonyday567@gmail.com+copyright:      Tony Day+license:        BSD3+license-file:   LICENSE+build-type:     Simple+cabal-version:  >= 1.18++extra-source-files:+    stack.yaml++source-repository head+  type: git+  location: https://github.com/tonyday567/numhask++library+  hs-source-dirs:+      src+  default-extensions: NegativeLiterals NoImplicitPrelude OverloadedStrings UnicodeSyntax+  ghc-options:+      -Wall+      -Wcompat+      -Wincomplete-record-updates+      -Wincomplete-uni-patterns+      -Wredundant-constraints+  build-depends:+      QuickCheck >=2.8 && <3+    , base >=4.7 && <4.12+    , numhask-prelude >=0.1.0.0 && <0.2+    , tasty >= 1.0.1.1 && <1.2+    , tasty-quickcheck >= 0.9.2 && <1.0+  exposed-modules:+      NumHask.Laws+  default-language: Haskell2010++test-suite test+  type: exitcode-stdio-1.0+  main-is: test.hs+  hs-source-dirs:+      test+  default-extensions: NegativeLiterals NoImplicitPrelude OverloadedStrings UnicodeSyntax+  build-depends:+      base >=4.7 && <5+    , QuickCheck >=2.8 && <3+    , numhask-test+    , numhask-prelude >= 0.1.0.0 && < 0.2+    , tasty+  default-language: Haskell2010
+ src/NumHask/Laws.hs view
@@ -0,0 +1,661 @@+{-# 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, 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 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, AdditiveGroup 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, Additive a, AdditiveGroup 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, Ord 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 -> case even ((floor $ a + one / (one + one)) :: Integer) of+        True  -> ((round a :: Integer) == (floor $ a + (one / (one + one))))+        False -> ((round a :: Integer) == (ceiling $ a - (one / (one + one))))+      )+    )+  ] where+    sign' a+      | (floor a :: Integer) < 0 = -1+      | otherwise = 1++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, Additive (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, Additive (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, Additive (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+    , Additive (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)+     , Additive (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++
+ stack.yaml view
@@ -0,0 +1,8 @@+resolver: nightly-2018-05-06++packages:+  - .+  - ../numhask+  - ../numhask-prelude++extra-deps: []
+ test/test.hs view
@@ -0,0 +1,351 @@+{-# 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 NumHask.Laws++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))++instance (Signed a, Arbitrary a, ExpField a) => Arbitrary (LogField a) where+  arbitrary = logField . abs <$> arbitrary++main :: IO ()+main = defaultMain tests++tests :: TestTree+tests =+  testGroup+    "NumHask"+    [ testsInt+    , testsInt8+    , testsInt16+    , testsInt32+    , testsInt64+    , testsWord+    , testsWord8+    , testsWord16+    , testsWord32+    , testsWord64+    , testsNatural+    , testsFloat+    , testsDouble+    , testsBool+    , testsComplexFloat+    , testsRational+    , testsLogFieldDouble+    ]++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" $ testLawOf2 ([] :: [(Rational, Integer)]) <$> quotientFieldLaws+    , testGroup "Upper Bounded Field" $ testLawOf ([] :: [Rational]) <$> upperBoundedFieldLaws+    , testGroup "Lower Bounded Field" $ testLawOf ([] :: [Rational]) <$> lowerBoundedFieldLaws+++    ]++    --  testGroup "Distribution" $ testLawOf ([] :: [Int]) <$> distributionLaws+    -- , testGroup "Metric" $ testLawOf2 ([] :: [(Int, Int)]) <$>+    --   metricIntegralLaws+    -- , testGroup "Normed or maxBound" $ testLawOf2 ([] :: [(Int, Int)]) <$> normedBoundedLaws++testsLogFieldDouble :: TestTree+testsLogFieldDouble =+  testGroup+    "LogField Double"+    [ testGroup "Additive - Associative Fail" $+      testLawOf ([] :: [LogField Double]) <$> additiveLawsFail+    , testGroup "Multiplicative - Associative Fail" $+      testLawOf ([] :: [LogField Double]) <$> multiplicativeLawsFail+    , testGroup "MultiplicativeGroup" $+      testLawOf ([] :: [LogField Double]) <$> multiplicativeGroupLaws_+    , testGroup "Distribution - Fail" $+      testLawOf ([] :: [LogField Double]) <$> distributionLawsFail+    ]