{-# LANGUAGE TemplateHaskell #-}
{-# OPTIONS_GHC -Wno-orphans #-}
{-# LANGUAGE PartialTypeSignatures #-}
{-# OPTIONS_GHC -Wno-partial-type-signatures #-}
module Numeric.MixedTypes.MinMaxAbs
(
CanMinMax, CanMinMaxAsymmetric(..), CanMinMaxThis, CanMinMaxSameType
, minimum, maximum
, specCanMinMax, specCanMinMaxNotMixed
, CanAbs(..), CanAbsSameType
, specCanNegNum, specCanAbs
)
where
import Utils.TH.DeclForTypes
import Numeric.MixedTypes.PreludeHiding
import qualified Prelude as P
import Text.Printf
import qualified Data.List as List
import Test.Hspec
import Test.QuickCheck
import Control.CollectErrors ( CollectErrors, CanBeErrors )
import qualified Control.CollectErrors as CE
import Numeric.MixedTypes.Literals
import Numeric.MixedTypes.Bool
import Numeric.MixedTypes.Eq
import Numeric.MixedTypes.Ord
type CanMinMax t1 t2 =
(CanMinMaxAsymmetric t1 t2, CanMinMaxAsymmetric t2 t1,
MinMaxType t1 t2 ~ MinMaxType t2 t1)
class CanMinMaxAsymmetric t1 t2 where
type MinMaxType t1 t2
type MinMaxType t1 t2 = t1
min :: t1 -> t2 -> MinMaxType t1 t2
max :: t1 -> t2 -> MinMaxType t1 t2
default min :: (MinMaxType t1 t2 ~ t1, t1~t2, P.Ord t1) => t1 -> t2 -> MinMaxType t1 t2
min = forall a. Ord a => a -> a -> a
P.min
default max :: (MinMaxType t1 t2 ~ t1, t1~t2, P.Ord t1) => t1 -> t2 -> MinMaxType t1 t2
max = forall a. Ord a => a -> a -> a
P.max
type CanMinMaxThis t1 t2 =
(CanMinMax t1 t2, MinMaxType t1 t2 ~ t1)
type CanMinMaxSameType t =
CanMinMaxThis t t
maximum :: (CanMinMaxSameType t) => [t] -> t
maximum :: forall t. CanMinMaxSameType t => [t] -> t
maximum (t
x:[t]
xs) = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
List.foldl' forall t1 t2.
CanMinMaxAsymmetric t1 t2 =>
t1 -> t2 -> MinMaxType t1 t2
max t
x [t]
xs
maximum [] = forall a. HasCallStack => [Char] -> a
error forall a b. (a -> b) -> a -> b
$ [Char]
"maximum: empty list"
minimum :: (CanMinMaxSameType t) => [t] -> t
minimum :: forall t. CanMinMaxSameType t => [t] -> t
minimum (t
x:[t]
xs) = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
List.foldl' forall t1 t2.
CanMinMaxAsymmetric t1 t2 =>
t1 -> t2 -> MinMaxType t1 t2
min t
x [t]
xs
minimum [] = forall a. HasCallStack => [Char] -> a
error forall a b. (a -> b) -> a -> b
$ [Char]
"minimum: empty list"
specCanMinMax ::
_ => T t1 -> T t2 -> T t3 -> Spec
specCanMinMax :: T t1 -> T t2 -> T t3 -> Spec
specCanMinMax (T [Char]
typeName1 :: T t1) (T [Char]
typeName2 :: T t2) (T [Char]
typeName3 :: T t3) =
forall a. HasCallStack => [Char] -> SpecWith a -> SpecWith a
describe (forall r. PrintfType r => [Char] -> r
printf [Char]
"CanMinMax %s %s, CanMinMax %s %s" [Char]
typeName1 [Char]
typeName2 [Char]
typeName2 [Char]
typeName3) forall a b. (a -> b) -> a -> b
$ do
forall a.
(HasCallStack, Example a) =>
[Char] -> a -> SpecWith (Arg a)
it [Char]
"`min` is not larger than its arguments" forall a b. (a -> b) -> a -> b
$ do
forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (t1
x :: t1) (t2
y :: t2) ->
(forall t. CanTestFinite t => t -> Bool
isFinite t1
x) forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&& (forall t. CanTestFinite t => t -> Bool
isFinite t2
y) forall prop. Testable prop => Bool -> prop -> Property
==>
let m :: MinMaxType t1 t2
m = t1
x forall t1 t2.
CanMinMaxAsymmetric t1 t2 =>
t1 -> t2 -> MinMaxType t1 t2
`min` t2
y in (MinMaxType t1 t2
m forall a b.
(HasOrderCertainlyAsymmetric a b, Show a, Show b) =>
a -> b -> Property
?<=?$ t2
y) forall prop1 prop2.
(Testable prop1, Testable prop2) =>
prop1 -> prop2 -> Property
.&&. (MinMaxType t1 t2
m forall a b.
(HasOrderCertainlyAsymmetric a b, Show a, Show b) =>
a -> b -> Property
?<=?$ t1
x)
forall a.
(HasCallStack, Example a) =>
[Char] -> a -> SpecWith (Arg a)
it [Char]
"`max` is not smaller than its arguments" forall a b. (a -> b) -> a -> b
$ do
forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (t1
x :: t1) (t2
y :: t2) ->
(forall t. CanTestFinite t => t -> Bool
isFinite t1
x) forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&& (forall t. CanTestFinite t => t -> Bool
isFinite t2
y) forall prop. Testable prop => Bool -> prop -> Property
==>
let m :: MinMaxType t1 t2
m = t1
x forall t1 t2.
CanMinMaxAsymmetric t1 t2 =>
t1 -> t2 -> MinMaxType t1 t2
`max` t2
y in (MinMaxType t1 t2
m forall a b.
(HasOrderCertainlyAsymmetric a b, Show a, Show b) =>
a -> b -> Property
?>=?$ t2
y) forall prop1 prop2.
(Testable prop1, Testable prop2) =>
prop1 -> prop2 -> Property
.&&. (MinMaxType t1 t2
m forall a b.
(HasOrderCertainlyAsymmetric a b, Show a, Show b) =>
a -> b -> Property
?>=?$ t1
x)
forall a.
(HasCallStack, Example a) =>
[Char] -> a -> SpecWith (Arg a)
it [Char]
"has idempotent `min`" forall a b. (a -> b) -> a -> b
$ do
forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (t1
x :: t1) ->
(forall t. CanTestFinite t => t -> Bool
isFinite t1
x) forall prop. Testable prop => Bool -> prop -> Property
==>
(t1
x forall t1 t2.
CanMinMaxAsymmetric t1 t2 =>
t1 -> t2 -> MinMaxType t1 t2
`min` t1
x) forall a b.
(HasEqCertainlyAsymmetric a b, Show a, Show b) =>
a -> b -> Property
?==?$ t1
x
forall a.
(HasCallStack, Example a) =>
[Char] -> a -> SpecWith (Arg a)
it [Char]
"has idempotent `max`" forall a b. (a -> b) -> a -> b
$ do
forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (t1
x :: t1) ->
(forall t. CanTestFinite t => t -> Bool
isFinite t1
x) forall prop. Testable prop => Bool -> prop -> Property
==>
(t1
x forall t1 t2.
CanMinMaxAsymmetric t1 t2 =>
t1 -> t2 -> MinMaxType t1 t2
`max` t1
x) forall a b.
(HasEqCertainlyAsymmetric a b, Show a, Show b) =>
a -> b -> Property
?==?$ t1
x
forall a.
(HasCallStack, Example a) =>
[Char] -> a -> SpecWith (Arg a)
it [Char]
"has commutative `min`" forall a b. (a -> b) -> a -> b
$ do
forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (t1
x :: t1) (t2
y :: t2) ->
(forall t. CanTestFinite t => t -> Bool
isFinite t1
x) forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&& (forall t. CanTestFinite t => t -> Bool
isFinite t2
y) forall prop. Testable prop => Bool -> prop -> Property
==>
(t1
x forall t1 t2.
CanMinMaxAsymmetric t1 t2 =>
t1 -> t2 -> MinMaxType t1 t2
`min` t2
y) forall a b.
(HasEqCertainlyAsymmetric a b, Show a, Show b) =>
a -> b -> Property
?==?$ (t2
y forall t1 t2.
CanMinMaxAsymmetric t1 t2 =>
t1 -> t2 -> MinMaxType t1 t2
`min` t1
x)
forall a.
(HasCallStack, Example a) =>
[Char] -> a -> SpecWith (Arg a)
it [Char]
"has commutative `max`" forall a b. (a -> b) -> a -> b
$ do
forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (t1
x :: t1) (t2
y :: t2) ->
(forall t. CanTestFinite t => t -> Bool
isFinite t1
x) forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&& (forall t. CanTestFinite t => t -> Bool
isFinite t2
y) forall prop. Testable prop => Bool -> prop -> Property
==>
(t1
x forall t1 t2.
CanMinMaxAsymmetric t1 t2 =>
t1 -> t2 -> MinMaxType t1 t2
`max` t2
y) forall a b.
(HasEqCertainlyAsymmetric a b, Show a, Show b) =>
a -> b -> Property
?==?$ (t2
y forall t1 t2.
CanMinMaxAsymmetric t1 t2 =>
t1 -> t2 -> MinMaxType t1 t2
`max` t1
x)
forall a.
(HasCallStack, Example a) =>
[Char] -> a -> SpecWith (Arg a)
it [Char]
"has associative `min`" forall a b. (a -> b) -> a -> b
$ do
forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (t1
x :: t1) (t2
y :: t2) (t3
z :: t3) ->
(forall t. CanTestFinite t => t -> Bool
isFinite t1
x) forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&& (forall t. CanTestFinite t => t -> Bool
isFinite t2
y) forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&& (forall t. CanTestFinite t => t -> Bool
isFinite t3
z) forall prop. Testable prop => Bool -> prop -> Property
==>
(t1
x forall t1 t2.
CanMinMaxAsymmetric t1 t2 =>
t1 -> t2 -> MinMaxType t1 t2
`min` (t2
y forall t1 t2.
CanMinMaxAsymmetric t1 t2 =>
t1 -> t2 -> MinMaxType t1 t2
`min` t3
z)) forall a b.
(HasEqCertainlyAsymmetric a b, Show a, Show b) =>
a -> b -> Property
?==?$ ((t1
x forall t1 t2.
CanMinMaxAsymmetric t1 t2 =>
t1 -> t2 -> MinMaxType t1 t2
`min` t2
y) forall t1 t2.
CanMinMaxAsymmetric t1 t2 =>
t1 -> t2 -> MinMaxType t1 t2
`min` t3
z)
forall a.
(HasCallStack, Example a) =>
[Char] -> a -> SpecWith (Arg a)
it [Char]
"has associative `max`" forall a b. (a -> b) -> a -> b
$ do
forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (t1
x :: t1) (t2
y :: t2) (t3
z :: t3) ->
(forall t. CanTestFinite t => t -> Bool
isFinite t1
x) forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&& (forall t. CanTestFinite t => t -> Bool
isFinite t2
y) forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&& (forall t. CanTestFinite t => t -> Bool
isFinite t3
z) forall prop. Testable prop => Bool -> prop -> Property
==>
(t1
x forall t1 t2.
CanMinMaxAsymmetric t1 t2 =>
t1 -> t2 -> MinMaxType t1 t2
`max` (t2
y forall t1 t2.
CanMinMaxAsymmetric t1 t2 =>
t1 -> t2 -> MinMaxType t1 t2
`max` t3
z)) forall a b.
(HasEqCertainlyAsymmetric a b, Show a, Show b) =>
a -> b -> Property
?==?$ ((t1
x forall t1 t2.
CanMinMaxAsymmetric t1 t2 =>
t1 -> t2 -> MinMaxType t1 t2
`max` t2
y) forall t1 t2.
CanMinMaxAsymmetric t1 t2 =>
t1 -> t2 -> MinMaxType t1 t2
`max` t3
z)
where
(?==?$) :: (HasEqCertainlyAsymmetric a b, Show a, Show b) => a -> b -> Property
?==?$ :: forall a b.
(HasEqCertainlyAsymmetric a b, Show a, Show b) =>
a -> b -> Property
(?==?$) = forall prop a b.
(Testable prop, Show a, Show b) =>
[Char] -> (a -> b -> prop) -> a -> b -> Property
printArgsIfFails2 [Char]
"?==?" forall a b. HasEqCertainlyAsymmetric a b => a -> b -> Bool
(?==?)
(?>=?$) :: (HasOrderCertainlyAsymmetric a b, Show a, Show b) => a -> b -> Property
?>=?$ :: forall a b.
(HasOrderCertainlyAsymmetric a b, Show a, Show b) =>
a -> b -> Property
(?>=?$) = forall prop a b.
(Testable prop, Show a, Show b) =>
[Char] -> (a -> b -> prop) -> a -> b -> Property
printArgsIfFails2 [Char]
"?>=?" forall a b. HasOrderCertainlyAsymmetric a b => a -> b -> Bool
(?>=?)
(?<=?$) :: (HasOrderCertainlyAsymmetric a b, Show a, Show b) => a -> b -> Property
?<=?$ :: forall a b.
(HasOrderCertainlyAsymmetric a b, Show a, Show b) =>
a -> b -> Property
(?<=?$) = forall prop a b.
(Testable prop, Show a, Show b) =>
[Char] -> (a -> b -> prop) -> a -> b -> Property
printArgsIfFails2 [Char]
"?<=?" forall a b. HasOrderCertainlyAsymmetric a b => a -> b -> Bool
(?<=?)
specCanMinMaxNotMixed ::
_ => T t -> Spec
specCanMinMaxNotMixed :: T t -> Spec
specCanMinMaxNotMixed T t
t = forall t1 t2 t3.
(HasOrderAsymmetric (MinMaxType t1 t2) t2,
HasOrderAsymmetric (MinMaxType t1 t2) t1, Arbitrary t1,
Arbitrary t2, Arbitrary t3, CanTestFinite t1, CanTestFinite t2,
CanTestFinite t3, HasEqAsymmetric (MinMaxType t1 t1) t1,
HasEqAsymmetric (MinMaxType t1 t2) (MinMaxType t2 t1),
HasEqAsymmetric
(MinMaxType t1 (MinMaxType t2 t3))
(MinMaxType (MinMaxType t1 t2) t3),
CanTestCertainly (OrderCompareType (MinMaxType t1 t2) t2),
CanTestCertainly (OrderCompareType (MinMaxType t1 t2) t1),
CanTestCertainly (EqCompareType (MinMaxType t1 t1) t1),
CanTestCertainly
(EqCompareType (MinMaxType t1 t2) (MinMaxType t2 t1)),
CanTestCertainly
(EqCompareType
(MinMaxType t1 (MinMaxType t2 t3))
(MinMaxType (MinMaxType t1 t2) t3)),
Show t1, Show t2, Show t3, Show (MinMaxType t2 t1),
Show (MinMaxType t1 t2), Show (MinMaxType t1 t1),
Show (MinMaxType t1 (MinMaxType t2 t3)),
Show (MinMaxType (MinMaxType t1 t2) t3), CanMinMaxAsymmetric t1 t2,
CanMinMaxAsymmetric t1 t1,
CanMinMaxAsymmetric t1 (MinMaxType t2 t3),
CanMinMaxAsymmetric t2 t1, CanMinMaxAsymmetric t2 t3,
CanMinMaxAsymmetric (MinMaxType t1 t2) t3) =>
T t1 -> T t2 -> T t3 -> Spec
specCanMinMax T t
t T t
t T t
t
instance CanMinMaxAsymmetric Int Int
instance CanMinMaxAsymmetric Integer Integer
instance CanMinMaxAsymmetric Rational Rational
instance CanMinMaxAsymmetric Double Double
instance CanMinMaxAsymmetric Int Integer where
type MinMaxType Int Integer = Integer
min :: Int -> Integer -> MinMaxType Int Integer
min = forall a b c.
ConvertibleExactly a b =>
(b -> b -> c) -> a -> b -> c
convertFirst forall t1 t2.
CanMinMaxAsymmetric t1 t2 =>
t1 -> t2 -> MinMaxType t1 t2
min
max :: Int -> Integer -> MinMaxType Int Integer
max = forall a b c.
ConvertibleExactly a b =>
(b -> b -> c) -> a -> b -> c
convertFirst forall t1 t2.
CanMinMaxAsymmetric t1 t2 =>
t1 -> t2 -> MinMaxType t1 t2
max
instance CanMinMaxAsymmetric Integer Int where
type MinMaxType Integer Int = Integer
min :: Integer -> Int -> MinMaxType Integer Int
min = forall b a c.
ConvertibleExactly b a =>
(a -> a -> c) -> a -> b -> c
convertSecond forall t1 t2.
CanMinMaxAsymmetric t1 t2 =>
t1 -> t2 -> MinMaxType t1 t2
min
max :: Integer -> Int -> MinMaxType Integer Int
max = forall b a c.
ConvertibleExactly b a =>
(a -> a -> c) -> a -> b -> c
convertSecond forall t1 t2.
CanMinMaxAsymmetric t1 t2 =>
t1 -> t2 -> MinMaxType t1 t2
max
$(declForTypes
[[t| Integer |], [t| Int |]]
(\ t -> [d|
instance CanMinMaxAsymmetric $t Rational where
type MinMaxType $t Rational = Rational
min = convertFirst min
max = convertFirst max
instance CanMinMaxAsymmetric Rational $t where
type MinMaxType Rational $t = Rational
min = convertSecond min
max = convertSecond max
|]))
$(declForTypes
[[t| Integer |], [t| Int |], [t| Rational |]]
(\ t -> [d|
instance
CanMinMaxAsymmetric $t Double
where
type MinMaxType $t Double = Double
min a b = min (double a) b
max a b = max (double a) b
instance
CanMinMaxAsymmetric Double $t
where
type MinMaxType Double $t = Double
min a b = min a (double b)
max a b = max a (double b)
|]))
instance (CanMinMaxAsymmetric a b) => CanMinMaxAsymmetric [a] [b] where
type MinMaxType [a] [b] = [MinMaxType a b]
min :: [a] -> [b] -> MinMaxType [a] [b]
min (a
x:[a]
xs) (b
y:[b]
ys) = (forall t1 t2.
CanMinMaxAsymmetric t1 t2 =>
t1 -> t2 -> MinMaxType t1 t2
min a
x b
y) forall a. a -> [a] -> [a]
: (forall t1 t2.
CanMinMaxAsymmetric t1 t2 =>
t1 -> t2 -> MinMaxType t1 t2
min [a]
xs [b]
ys)
min [a]
_ [b]
_ = []
max :: [a] -> [b] -> MinMaxType [a] [b]
max (a
x:[a]
xs) (b
y:[b]
ys) = (forall t1 t2.
CanMinMaxAsymmetric t1 t2 =>
t1 -> t2 -> MinMaxType t1 t2
max a
x b
y) forall a. a -> [a] -> [a]
: (forall t1 t2.
CanMinMaxAsymmetric t1 t2 =>
t1 -> t2 -> MinMaxType t1 t2
max [a]
xs [b]
ys)
max [a]
_ [b]
_ = []
instance (CanMinMaxAsymmetric a b) => CanMinMaxAsymmetric (Maybe a) (Maybe b) where
type MinMaxType (Maybe a) (Maybe b) = Maybe (MinMaxType a b)
min :: Maybe a -> Maybe b -> MinMaxType (Maybe a) (Maybe b)
min (Just a
x) (Just b
y) = forall a. a -> Maybe a
Just (forall t1 t2.
CanMinMaxAsymmetric t1 t2 =>
t1 -> t2 -> MinMaxType t1 t2
min a
x b
y)
min Maybe a
_ Maybe b
_ = forall a. Maybe a
Nothing
max :: Maybe a -> Maybe b -> MinMaxType (Maybe a) (Maybe b)
max (Just a
x) (Just b
y) = forall a. a -> Maybe a
Just (forall t1 t2.
CanMinMaxAsymmetric t1 t2 =>
t1 -> t2 -> MinMaxType t1 t2
max a
x b
y)
max Maybe a
_ Maybe b
_ = forall a. Maybe a
Nothing
instance
(CanMinMaxAsymmetric a b, CanBeErrors es)
=>
CanMinMaxAsymmetric (CollectErrors es a) (CollectErrors es b)
where
type MinMaxType (CollectErrors es a) (CollectErrors es b) =
CollectErrors es (MinMaxType a b)
min :: CollectErrors es a
-> CollectErrors es b
-> MinMaxType (CollectErrors es a) (CollectErrors es b)
min = forall es a b c.
Monoid es =>
(a -> b -> c)
-> CollectErrors es a -> CollectErrors es b -> CollectErrors es c
CE.lift2 forall t1 t2.
CanMinMaxAsymmetric t1 t2 =>
t1 -> t2 -> MinMaxType t1 t2
min
max :: CollectErrors es a
-> CollectErrors es b
-> MinMaxType (CollectErrors es a) (CollectErrors es b)
max = forall es a b c.
Monoid es =>
(a -> b -> c)
-> CollectErrors es a -> CollectErrors es b -> CollectErrors es c
CE.lift2 forall t1 t2.
CanMinMaxAsymmetric t1 t2 =>
t1 -> t2 -> MinMaxType t1 t2
max
$(declForTypes
[[t| Integer |], [t| Int |], [t| Rational |], [t| Double |]]
(\ t -> [d|
instance
(CanMinMaxAsymmetric $t b, CanBeErrors es)
=>
CanMinMaxAsymmetric $t (CollectErrors es b)
where
type MinMaxType $t (CollectErrors es b) =
CollectErrors es (MinMaxType $t b)
min = CE.liftT1 min
max = CE.liftT1 max
instance
(CanMinMaxAsymmetric a $t, CanBeErrors es)
=>
CanMinMaxAsymmetric (CollectErrors es a) $t
where
type MinMaxType (CollectErrors es a) $t =
CollectErrors es (MinMaxType a $t)
min = CE.lift1T min
max = CE.lift1T max
|]))
specCanNegNum ::
_ => T t -> Spec
specCanNegNum :: T t -> Spec
specCanNegNum (T [Char]
typeName :: T t) =
forall a. HasCallStack => [Char] -> SpecWith a -> SpecWith a
describe (forall r. PrintfType r => [Char] -> r
printf [Char]
"CanNeg %s" [Char]
typeName) forall a b. (a -> b) -> a -> b
$ do
forall a.
(HasCallStack, Example a) =>
[Char] -> a -> SpecWith (Arg a)
it [Char]
"ignores double negation" forall a b. (a -> b) -> a -> b
$ do
forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (t
x :: t) ->
(t
x forall a b. HasEqCertainlyAsymmetric a b => a -> b -> Bool
?==? t
x) forall prop. Testable prop => Bool -> prop -> Property
==>
(forall t. CanNeg t => t -> NegType t
negate (forall t. CanNeg t => t -> NegType t
negate t
x)) forall a b.
(HasEqCertainlyAsymmetric a b, Show a, Show b) =>
a -> b -> Property
?==?$ t
x
forall a.
(HasCallStack, Example a) =>
[Char] -> a -> SpecWith (Arg a)
it [Char]
"takes 0 to 0" forall a b. (a -> b) -> a -> b
$ do
let z :: t
z = forall t1 t2. ConvertibleExactly t1 t2 => t1 -> t2
convertExactly Integer
0 :: t in forall t. CanNeg t => t -> NegType t
negate t
z forall a b. HasEqCertainlyAsymmetric a b => a -> b -> Bool
?==? t
z
forall a.
(HasCallStack, Example a) =>
[Char] -> a -> SpecWith (Arg a)
it [Char]
"takes positive to negative" forall a b. (a -> b) -> a -> b
$ do
forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (t
x :: t) ->
(forall t. CanTestFinite t => t -> Bool
isFinite t
x) forall prop. Testable prop => Bool -> prop -> Property
==>
(forall t. CanTestPosNeg t => t -> Bool
isCertainlyPositive t
x) forall prop. Testable prop => Bool -> prop -> Property
==> (forall t. CanTestPosNeg t => t -> Bool
isCertainlyNegative (forall t. CanNeg t => t -> NegType t
negate t
x))
forall a.
(HasCallStack, Example a) =>
[Char] -> a -> SpecWith (Arg a)
it [Char]
"takes negative to positive" forall a b. (a -> b) -> a -> b
$ do
forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (t
x :: t) ->
(forall t. CanTestFinite t => t -> Bool
isFinite t
x) forall prop. Testable prop => Bool -> prop -> Property
==>
(forall t. CanTestPosNeg t => t -> Bool
isCertainlyNegative t
x) forall prop. Testable prop => Bool -> prop -> Property
==> (forall t. CanTestPosNeg t => t -> Bool
isCertainlyPositive (forall t. CanNeg t => t -> NegType t
negate t
x))
where
(?==?$) :: (HasEqCertainlyAsymmetric a b, Show a, Show b) => a -> b -> Property
?==?$ :: forall a b.
(HasEqCertainlyAsymmetric a b, Show a, Show b) =>
a -> b -> Property
(?==?$) = forall prop a b.
(Testable prop, Show a, Show b) =>
[Char] -> (a -> b -> prop) -> a -> b -> Property
printArgsIfFails2 [Char]
"?==?" forall a b. HasEqCertainlyAsymmetric a b => a -> b -> Bool
(?==?)
instance CanNeg Int where negate :: Int -> NegType Int
negate = forall a. Num a => a -> a
P.negate
instance CanNeg Integer where negate :: Integer -> NegType Integer
negate = forall a. Num a => a -> a
P.negate
instance CanNeg Rational where negate :: Rational -> NegType Rational
negate = forall a. Num a => a -> a
P.negate
instance CanNeg Double where negate :: Double -> NegType Double
negate = forall a. Num a => a -> a
P.negate
class CanAbs t where
type AbsType t
type AbsType t = t
abs :: t -> AbsType t
default abs :: (AbsType t ~ t, P.Num t) => t -> AbsType t
abs = forall a. Num a => a -> a
P.abs
type CanAbsSameType t = (CanAbs t, AbsType t ~ t)
instance CanAbs Int
instance CanAbs Integer
instance CanAbs Rational
instance CanAbs Double
instance
(CanAbs a, CanBeErrors es)
=>
CanAbs (CollectErrors es a)
where
type AbsType (CollectErrors es a) = CollectErrors es (AbsType a)
abs :: CollectErrors es a -> AbsType (CollectErrors es a)
abs = forall es a b.
Monoid es =>
(a -> b) -> CollectErrors es a -> CollectErrors es b
CE.lift forall t. CanAbs t => t -> AbsType t
abs
specCanAbs ::
_ => T t -> Spec
specCanAbs :: T t -> Spec
specCanAbs (T [Char]
typeName :: T t) =
forall a. HasCallStack => [Char] -> SpecWith a -> SpecWith a
describe (forall r. PrintfType r => [Char] -> r
printf [Char]
"CanAbs %s" [Char]
typeName) forall a b. (a -> b) -> a -> b
$ do
forall a.
(HasCallStack, Example a) =>
[Char] -> a -> SpecWith (Arg a)
it [Char]
"is idempotent" forall a b. (a -> b) -> a -> b
$ do
forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (t
x :: t) ->
(t
x forall a b. HasEqCertainlyAsymmetric a b => a -> b -> Bool
?==? t
x) forall prop. Testable prop => Bool -> prop -> Property
==>
(forall t. CanAbs t => t -> AbsType t
abs (forall t. CanAbs t => t -> AbsType t
abs t
x)) forall a b.
(HasEqCertainlyAsymmetric a b, Show a, Show b) =>
a -> b -> Property
?==?$ (forall t. CanAbs t => t -> AbsType t
abs t
x)
forall a.
(HasCallStack, Example a) =>
[Char] -> a -> SpecWith (Arg a)
it [Char]
"is identity on non-negative arguments" forall a b. (a -> b) -> a -> b
$ do
forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (t
x :: t) ->
(forall t. CanTestFinite t => t -> Bool
isFinite t
x) forall prop. Testable prop => Bool -> prop -> Property
==>
forall t. CanTestPosNeg t => t -> Bool
isCertainlyNonNegative t
x forall prop. Testable prop => Bool -> prop -> Property
==> t
x forall a b.
(HasEqCertainlyAsymmetric a b, Show a, Show b) =>
a -> b -> Property
?==?$ (forall t. CanAbs t => t -> AbsType t
abs t
x)
forall a.
(HasCallStack, Example a) =>
[Char] -> a -> SpecWith (Arg a)
it [Char]
"is negation on non-positive arguments" forall a b. (a -> b) -> a -> b
$ do
forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (t
x :: t) ->
(forall t. CanTestFinite t => t -> Bool
isFinite t
x) forall prop. Testable prop => Bool -> prop -> Property
==>
forall t. CanTestPosNeg t => t -> Bool
isCertainlyNonPositive t
x forall prop. Testable prop => Bool -> prop -> Property
==> (forall t. CanNeg t => t -> NegType t
negate t
x) forall a b.
(HasEqCertainlyAsymmetric a b, Show a, Show b) =>
a -> b -> Property
?==?$ (forall t. CanAbs t => t -> AbsType t
abs t
x)
forall a.
(HasCallStack, Example a) =>
[Char] -> a -> SpecWith (Arg a)
it [Char]
"does not give negative results" forall a b. (a -> b) -> a -> b
$ do
forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (t
x :: t) ->
(forall t. CanTestFinite t => t -> Bool
isFinite t
x) forall prop. Testable prop => Bool -> prop -> Property
==>
forall t. CanNeg t => t -> NegType t
not forall a b. (a -> b) -> a -> b
$ forall t. CanTestPosNeg t => t -> Bool
isCertainlyNegative (forall t. CanAbs t => t -> AbsType t
abs t
x)
where
(?==?$) :: (HasEqCertainlyAsymmetric a b, Show a, Show b) => a -> b -> Property
?==?$ :: forall a b.
(HasEqCertainlyAsymmetric a b, Show a, Show b) =>
a -> b -> Property
(?==?$) = forall prop a b.
(Testable prop, Show a, Show b) =>
[Char] -> (a -> b -> prop) -> a -> b -> Property
printArgsIfFails2 [Char]
"?==?" forall a b. HasEqCertainlyAsymmetric a b => a -> b -> Bool
(?==?)