packages feed

semiring-num 0.8.0.0 → 0.9.0.0

raw patch · 7 files changed

+233/−30 lines, 7 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Data.Semiring: instance (GHC.Classes.Eq a, Data.Semiring.Semiring a) => Data.Semiring.StarSemiring (Data.Semiring.Infinite.PositiveInfinite a)
- Data.Semiring: instance Data.Semiring.Semiring a => Data.Semiring.Semiring (Data.Functor.Const.Const a b)
- Data.Semiring: instance Data.Semiring.Semiring a => Data.Semiring.Semiring (Data.Semiring.Infinite.Infinite a)
- Data.Semiring: instance Data.Semiring.Semiring a => Data.Semiring.Semiring (Data.Semiring.Infinite.NegativeInfinite a)
- Data.Semiring: instance Data.Semiring.Semiring a => Data.Semiring.Semiring (Data.Semiring.Infinite.PositiveInfinite a)
- Test.Semiring: nearUnLaws :: (Eq a, Semiring a, Show a) => a -> Either String String
+ Data.Semiring: class Semiring a => DetectableZero a where isZero = (zero ==)
+ Data.Semiring: instance (Data.Semiring.DetectableZero a0, Data.Semiring.DetectableZero a1) => Data.Semiring.DetectableZero (a0, a1)
+ Data.Semiring: instance (Data.Semiring.DetectableZero a0, Data.Semiring.DetectableZero a1, Data.Semiring.DetectableZero a2) => Data.Semiring.DetectableZero (a0, a1, a2)
+ Data.Semiring: instance (Data.Semiring.DetectableZero a0, Data.Semiring.DetectableZero a1, Data.Semiring.DetectableZero a2, Data.Semiring.DetectableZero a3) => Data.Semiring.DetectableZero (a0, a1, a2, a3)
+ Data.Semiring: instance (Data.Semiring.DetectableZero a0, Data.Semiring.DetectableZero a1, Data.Semiring.DetectableZero a2, Data.Semiring.DetectableZero a3, Data.Semiring.DetectableZero a4) => Data.Semiring.DetectableZero (a0, a1, a2, a3, a4)
+ Data.Semiring: instance (Data.Semiring.DetectableZero a0, Data.Semiring.DetectableZero a1, Data.Semiring.DetectableZero a2, Data.Semiring.DetectableZero a3, Data.Semiring.DetectableZero a4, Data.Semiring.DetectableZero a5) => Data.Semiring.DetectableZero (a0, a1, a2, a3, a4, a5)
+ Data.Semiring: instance (Data.Semiring.DetectableZero a0, Data.Semiring.DetectableZero a1, Data.Semiring.DetectableZero a2, Data.Semiring.DetectableZero a3, Data.Semiring.DetectableZero a4, Data.Semiring.DetectableZero a5, Data.Semiring.DetectableZero a6) => Data.Semiring.DetectableZero (a0, a1, a2, a3, a4, a5, a6)
+ Data.Semiring: instance (Data.Semiring.DetectableZero a0, Data.Semiring.DetectableZero a1, Data.Semiring.DetectableZero a2, Data.Semiring.DetectableZero a3, Data.Semiring.DetectableZero a4, Data.Semiring.DetectableZero a5, Data.Semiring.DetectableZero a6, Data.Semiring.DetectableZero a7) => Data.Semiring.DetectableZero (a0, a1, a2, a3, a4, a5, a6, a7)
+ Data.Semiring: instance (Data.Semiring.DetectableZero a0, Data.Semiring.DetectableZero a1, Data.Semiring.DetectableZero a2, Data.Semiring.DetectableZero a3, Data.Semiring.DetectableZero a4, Data.Semiring.DetectableZero a5, Data.Semiring.DetectableZero a6, Data.Semiring.DetectableZero a7, Data.Semiring.DetectableZero a8) => Data.Semiring.DetectableZero (a0, a1, a2, a3, a4, a5, a6, a7, a8)
+ Data.Semiring: instance (Data.Semiring.Semiring a, GHC.Classes.Ord a, Data.Semiring.Infinite.HasNegativeInfinity a) => Data.Semiring.DetectableZero (Data.Semiring.Max a)
+ Data.Semiring: instance (Data.Semiring.Semiring a, GHC.Classes.Ord a, Data.Semiring.Infinite.HasPositiveInfinity a) => Data.Semiring.DetectableZero (Data.Semiring.Min a)
+ Data.Semiring: instance (GHC.Enum.Enum a, GHC.Enum.Bounded a, GHC.Classes.Eq a, GHC.Base.Monoid a) => Data.Semiring.DetectableZero (Data.Monoid.Endo a)
+ Data.Semiring: instance Data.Fixed.HasResolution a => Data.Semiring.DetectableZero (Data.Fixed.Fixed a)
+ Data.Semiring: instance Data.Semiring.DetectableZero ()
+ Data.Semiring: instance Data.Semiring.DetectableZero Data.Monoid.All
+ Data.Semiring: instance Data.Semiring.DetectableZero Data.Monoid.Any
+ Data.Semiring: instance Data.Semiring.DetectableZero Foreign.C.Types.CChar
+ Data.Semiring: instance Data.Semiring.DetectableZero Foreign.C.Types.CClock
+ Data.Semiring: instance Data.Semiring.DetectableZero Foreign.C.Types.CDouble
+ Data.Semiring: instance Data.Semiring.DetectableZero Foreign.C.Types.CFloat
+ Data.Semiring: instance Data.Semiring.DetectableZero Foreign.C.Types.CInt
+ Data.Semiring: instance Data.Semiring.DetectableZero Foreign.C.Types.CIntMax
+ Data.Semiring: instance Data.Semiring.DetectableZero Foreign.C.Types.CIntPtr
+ Data.Semiring: instance Data.Semiring.DetectableZero Foreign.C.Types.CLLong
+ Data.Semiring: instance Data.Semiring.DetectableZero Foreign.C.Types.CLong
+ Data.Semiring: instance Data.Semiring.DetectableZero Foreign.C.Types.CPtrdiff
+ Data.Semiring: instance Data.Semiring.DetectableZero Foreign.C.Types.CSChar
+ Data.Semiring: instance Data.Semiring.DetectableZero Foreign.C.Types.CSUSeconds
+ Data.Semiring: instance Data.Semiring.DetectableZero Foreign.C.Types.CShort
+ Data.Semiring: instance Data.Semiring.DetectableZero Foreign.C.Types.CSigAtomic
+ Data.Semiring: instance Data.Semiring.DetectableZero Foreign.C.Types.CSize
+ Data.Semiring: instance Data.Semiring.DetectableZero Foreign.C.Types.CTime
+ Data.Semiring: instance Data.Semiring.DetectableZero Foreign.C.Types.CUChar
+ Data.Semiring: instance Data.Semiring.DetectableZero Foreign.C.Types.CUInt
+ Data.Semiring: instance Data.Semiring.DetectableZero Foreign.C.Types.CUIntMax
+ Data.Semiring: instance Data.Semiring.DetectableZero Foreign.C.Types.CUIntPtr
+ Data.Semiring: instance Data.Semiring.DetectableZero Foreign.C.Types.CULLong
+ Data.Semiring: instance Data.Semiring.DetectableZero Foreign.C.Types.CULong
+ Data.Semiring: instance Data.Semiring.DetectableZero Foreign.C.Types.CUSeconds
+ Data.Semiring: instance Data.Semiring.DetectableZero Foreign.C.Types.CUShort
+ Data.Semiring: instance Data.Semiring.DetectableZero Foreign.C.Types.CWchar
+ Data.Semiring: instance Data.Semiring.DetectableZero Foreign.Ptr.IntPtr
+ Data.Semiring: instance Data.Semiring.DetectableZero Foreign.Ptr.WordPtr
+ Data.Semiring: instance Data.Semiring.DetectableZero GHC.Int.Int16
+ Data.Semiring: instance Data.Semiring.DetectableZero GHC.Int.Int32
+ Data.Semiring: instance Data.Semiring.DetectableZero GHC.Int.Int64
+ Data.Semiring: instance Data.Semiring.DetectableZero GHC.Int.Int8
+ Data.Semiring: instance Data.Semiring.DetectableZero GHC.Integer.Type.Integer
+ Data.Semiring: instance Data.Semiring.DetectableZero GHC.Natural.Natural
+ Data.Semiring: instance Data.Semiring.DetectableZero GHC.Types.Bool
+ Data.Semiring: instance Data.Semiring.DetectableZero GHC.Types.Double
+ Data.Semiring: instance Data.Semiring.DetectableZero GHC.Types.Float
+ Data.Semiring: instance Data.Semiring.DetectableZero GHC.Types.Int
+ Data.Semiring: instance Data.Semiring.DetectableZero GHC.Types.Word
+ Data.Semiring: instance Data.Semiring.DetectableZero GHC.Word.Word16
+ Data.Semiring: instance Data.Semiring.DetectableZero GHC.Word.Word32
+ Data.Semiring: instance Data.Semiring.DetectableZero GHC.Word.Word64
+ Data.Semiring: instance Data.Semiring.DetectableZero GHC.Word.Word8
+ Data.Semiring: instance Data.Semiring.DetectableZero System.Posix.Types.CCc
+ Data.Semiring: instance Data.Semiring.DetectableZero System.Posix.Types.CDev
+ Data.Semiring: instance Data.Semiring.DetectableZero System.Posix.Types.CGid
+ Data.Semiring: instance Data.Semiring.DetectableZero System.Posix.Types.CIno
+ Data.Semiring: instance Data.Semiring.DetectableZero System.Posix.Types.CMode
+ Data.Semiring: instance Data.Semiring.DetectableZero System.Posix.Types.CNlink
+ Data.Semiring: instance Data.Semiring.DetectableZero System.Posix.Types.COff
+ Data.Semiring: instance Data.Semiring.DetectableZero System.Posix.Types.CPid
+ Data.Semiring: instance Data.Semiring.DetectableZero System.Posix.Types.CRLim
+ Data.Semiring: instance Data.Semiring.DetectableZero System.Posix.Types.CSpeed
+ Data.Semiring: instance Data.Semiring.DetectableZero System.Posix.Types.CSsize
+ Data.Semiring: instance Data.Semiring.DetectableZero System.Posix.Types.CTcflag
+ Data.Semiring: instance Data.Semiring.DetectableZero System.Posix.Types.CUid
+ Data.Semiring: instance Data.Semiring.DetectableZero System.Posix.Types.Fd
+ Data.Semiring: instance Data.Semiring.DetectableZero a => Data.Semiring.DetectableZero (Data.Functor.Identity.Identity a)
+ Data.Semiring: instance Data.Semiring.DetectableZero a => Data.Semiring.DetectableZero (Data.Monoid.Product a)
+ Data.Semiring: instance Data.Semiring.DetectableZero a => Data.Semiring.DetectableZero (Data.Monoid.Sum a)
+ Data.Semiring: instance Data.Semiring.DetectableZero a => Data.Semiring.DetectableZero (Data.Semiring.Add a)
+ Data.Semiring: instance Data.Semiring.DetectableZero a => Data.Semiring.DetectableZero (Data.Semiring.Infinite.Infinite a)
+ Data.Semiring: instance Data.Semiring.DetectableZero a => Data.Semiring.DetectableZero (Data.Semiring.Infinite.NegativeInfinite a)
+ Data.Semiring: instance Data.Semiring.DetectableZero a => Data.Semiring.DetectableZero (Data.Semiring.Infinite.PositiveInfinite a)
+ Data.Semiring: instance Data.Semiring.DetectableZero a => Data.Semiring.DetectableZero (Data.Semiring.Mul a)
+ Data.Semiring: instance Data.Semiring.DetectableZero a => Data.Semiring.Semiring (Data.Semiring.Infinite.Infinite a)
+ Data.Semiring: instance Data.Semiring.DetectableZero a => Data.Semiring.Semiring (Data.Semiring.Infinite.NegativeInfinite a)
+ Data.Semiring: instance Data.Semiring.DetectableZero a => Data.Semiring.Semiring (Data.Semiring.Infinite.PositiveInfinite a)
+ Data.Semiring: instance Data.Semiring.DetectableZero a => Data.Semiring.StarSemiring (Data.Semiring.Infinite.PositiveInfinite a)
+ Data.Semiring: instance Data.Semiring.Semiring a => Data.Semiring.DetectableZero [a]
+ Data.Semiring: instance GHC.Float.RealFloat a => Data.Semiring.DetectableZero (Data.Complex.Complex a)
+ Data.Semiring: instance GHC.Real.Integral a => Data.Semiring.DetectableZero (GHC.Real.Ratio a)
+ Data.Semiring: isNegativeInfinity :: (HasNegativeInfinity a, RealFloat a) => a -> Bool
+ Data.Semiring: isPositiveInfinity :: (HasPositiveInfinity a, RealFloat a) => a -> Bool
+ Data.Semiring: isZero :: (DetectableZero a, Eq a) => a -> Bool
+ Data.Semiring.Numeric: instance (GHC.Classes.Eq a, Data.Semiring.Semiring a) => Data.Semiring.DetectableZero (Data.Semiring.Numeric.PosFrac a)
+ Data.Semiring.Numeric: instance (GHC.Classes.Eq a, Data.Semiring.Semiring a) => Data.Semiring.DetectableZero (Data.Semiring.Numeric.PosInt a)
+ Data.Semiring.Numeric: instance (GHC.Classes.Ord a, Data.Semiring.DetectableZero a) => Data.Semiring.DetectableZero (Data.Semiring.Numeric.Viterbi a)
+ Data.Semiring.Numeric: instance (GHC.Classes.Ord a, GHC.Num.Num a) => Data.Semiring.DetectableZero (Data.Semiring.Numeric.Łukasiewicz a)
+ Data.Semiring.Numeric: instance (GHC.Enum.Bounded a, GHC.Classes.Ord a) => Data.Semiring.DetectableZero (Data.Semiring.Numeric.Bottleneck a)
+ Data.Semiring.Numeric: instance (GHC.Float.Floating a, Data.Semiring.Infinite.HasPositiveInfinity a) => Data.Semiring.DetectableZero (Data.Semiring.Numeric.Log a)
+ Data.Semiring.Numeric: instance (GHC.Real.Integral a, Data.Semiring.DetectableZero a) => Data.Semiring.DetectableZero (Data.Semiring.Numeric.Division a)
+ Test.Semiring: nearUnaryLaws :: (Eq a, Semiring a, Show a) => a -> Either String String
+ Test.Semiring: zeroIsZero :: (DetectableZero a, Show a) => f a -> Either String String
+ Test.Semiring: zeroLaw :: (Eq a, DetectableZero a, Show a) => a -> Either String String
+ Test.Semiring: zeroLaws :: (DetectableZero a, Show a, Eq a) => a -> Either String String
- Data.Semiring: class HasNegativeInfinity a where negativeInfinity = negate (1 / 0)
+ Data.Semiring: class HasNegativeInfinity a where negativeInfinity = negate (1 / 0) isNegativeInfinity x = isInfinite x && x < 0
- Data.Semiring: class HasPositiveInfinity a where positiveInfinity = 1 / 0
+ Data.Semiring: class HasPositiveInfinity a where positiveInfinity = 1 / 0 isPositiveInfinity x = isInfinite x && x > 0

Files

semiring-num.cabal view
@@ -1,5 +1,5 @@ name:                semiring-num-version:             0.8.0.0+version:             0.9.0.0 synopsis:            Basic semiring class and instances description:         Adds a basic semiring class homepage:            https://github.com/oisdk/semiring-num
src/Data/Semiring.hs view
@@ -29,9 +29,9 @@   , mul   , Max(..)   , Min(..)+  , DetectableZero(..)   ) where -import           Data.Functor.Const    (Const (..)) import           Data.Functor.Identity (Identity (..))  import           Data.Complex          (Complex)@@ -146,6 +146,11 @@     star x = one <+> plus x     plus x = x <.> star x +class Semiring a => DetectableZero a where+  isZero :: a -> Bool+  default isZero :: Eq a => a -> Bool+  isZero = (zero==)+ ------------------------------------------------------------------------ -- Instances ------------------------------------------------------------------------@@ -167,52 +172,69 @@     {-# INLINE star #-}     {-# INLINE plus #-} +instance DetectableZero Bool+ -- | Not lawful. Only for convenience.-instance Semiring a =>+instance DetectableZero a =>          Semiring (NegativeInfinite a) where     one = pure one     zero = pure zero     (<+>) =         (coerce :: CoerceBinary (NegativeInfinite (Add a)) (NegativeInfinite a))             mappend-    (<.>) = liftA2 (<.>)+    x <.> y | any isZero x || any isZero y = zero+            | otherwise = liftA2 (<.>) x y     {-# INLINE zero #-}     {-# INLINE one #-}     {-# INLINE (<+>) #-}     {-# INLINE (<.>) #-}  -- | Not lawful. Only for convenience.-instance Semiring a =>+instance (DetectableZero a) =>          Semiring (PositiveInfinite a) where     one = pure one     zero = pure zero     (<+>) =         (coerce :: CoerceBinary (PositiveInfinite (Add a)) (PositiveInfinite a))             mappend-    (<.>) = liftA2 (<.>)+    x <.> y | any isZero x || any isZero y = zero+            | otherwise = liftA2 (<.>) x y     {-# INLINE zero #-}     {-# INLINE one #-}     {-# INLINE (<+>) #-}     {-# INLINE (<.>) #-}  -- | Not lawful. Only for convenience.-instance Semiring a =>+instance (DetectableZero a) =>          Semiring (Infinite a) where     one = pure one     zero = pure zero     (<+>) = (coerce :: CoerceBinary (Infinite (Add a)) (Infinite a)) mappend-    (<.>) = liftA2 (<.>)+    x <.> y | any isZero x || any isZero y = zero+            | otherwise = liftA2 (<.>) x y     {-# INLINE zero #-}     {-# INLINE one #-}     {-# INLINE (<+>) #-}     {-# INLINE (<.>) #-} -instance (Eq a, Semiring a) =>+instance (DetectableZero a) =>          StarSemiring (PositiveInfinite a) where     star (PosFinite x)-      | x == zero = one+      | isZero x = one     star _ = PositiveInfinity +instance DetectableZero a =>+         DetectableZero (NegativeInfinite a) where+    isZero = any isZero++instance DetectableZero a =>+         DetectableZero (PositiveInfinite a) where+    isZero = any isZero++instance DetectableZero a =>+         DetectableZero (Infinite a) where+    isZero = any isZero+ instance Semiring () where     one = ()     zero = ()@@ -223,6 +245,8 @@     {-# INLINE (<+>) #-}     {-# INLINE (<.>) #-} +instance DetectableZero ()+ instance StarSemiring () where     star _ = ()     plus _ = ()@@ -244,6 +268,9 @@     (x:xs) <.> (y:ys) =         (x <.> y) : (map (x <.>) ys <+> map (<.> y) xs <+> (xs <.> ys)) +instance Semiring a => DetectableZero [a] where+  isZero = null+ ------------------------------------------------------------------------ -- Addition and multiplication newtypes ------------------------------------------------------------------------@@ -255,7 +282,7 @@     { getAdd :: a     } deriving (Eq,Ord,Read,Show,Bounded,Generic,Generic1,Num,Enum,Typeable                ,Storable,Fractional,Real,RealFrac,Functor,Foldable,Traversable-               ,Semiring,StarSemiring)+               ,Semiring,StarSemiring,DetectableZero)  -- | Monoid under '<.>'. Analogous to 'Data.Monoid.Product', but uses the -- 'Semiring' constraint, rather than 'Num'.@@ -263,7 +290,7 @@     { getMul :: a     } deriving (Eq,Ord,Read,Show,Bounded,Generic,Generic1,Num,Enum,Typeable                ,Storable,Fractional,Real,RealFrac,Functor,Foldable,Traversable-               ,Semiring,StarSemiring)+               ,Semiring,StarSemiring,DetectableZero)  instance Semiring a =>          Semigroup (Add a) where@@ -429,6 +456,12 @@       | x < zero = Min negativeInfinity       | otherwise = Min zero +instance (Semiring a, Ord a, HasPositiveInfinity a) => DetectableZero (Min a) where+  isZero (Min x) = isPositiveInfinity x++instance (Semiring a, Ord a, HasNegativeInfinity a) => DetectableZero (Max a) where+  isZero (Max x) = isNegativeInfinity x+ ------------------------------------------------------------------------ -- (->) instance ------------------------------------------------------------------------@@ -482,6 +515,9 @@               where                 next = mappend x (f inp) +instance (Enum a, Bounded a, Eq a, Monoid a) => DetectableZero (Endo a) where+  isZero (Endo f) = all (mempty==) (map f [minBound..maxBound])+ ------------------------------------------------------------------------ -- Instances for Bool wrappers ------------------------------------------------------------------------@@ -517,6 +553,9 @@     {-# INLINE star #-}     {-# INLINE plus #-} +instance DetectableZero Any+instance DetectableZero All+ ------------------------------------------------------------------------ -- Boring instances ------------------------------------------------------------------------@@ -582,11 +621,73 @@ instance RealFloat a => Semiring (Complex a) instance HasResolution a => Semiring (Fixed a) deriving instance Semiring a => Semiring (Identity a)-deriving instance Semiring a => Semiring (Const a b) +instance DetectableZero Int+instance DetectableZero Int8+instance DetectableZero Int16+instance DetectableZero Int32+instance DetectableZero Int64+instance DetectableZero Integer+instance DetectableZero Word+instance DetectableZero Word8+instance DetectableZero Word16+instance DetectableZero Word32+instance DetectableZero Word64+instance DetectableZero Float+instance DetectableZero Double+instance DetectableZero CUIntMax+instance DetectableZero CIntMax+instance DetectableZero CUIntPtr+instance DetectableZero CIntPtr+instance DetectableZero CSUSeconds+instance DetectableZero CUSeconds+instance DetectableZero CTime+instance DetectableZero CClock+instance DetectableZero CSigAtomic+instance DetectableZero CWchar+instance DetectableZero CSize+instance DetectableZero CPtrdiff+instance DetectableZero CDouble+instance DetectableZero CFloat+instance DetectableZero CULLong+instance DetectableZero CLLong+instance DetectableZero CULong+instance DetectableZero CLong+instance DetectableZero CUInt+instance DetectableZero CInt+instance DetectableZero CUShort+instance DetectableZero CShort+instance DetectableZero CUChar+instance DetectableZero CSChar+instance DetectableZero CChar+instance DetectableZero IntPtr+instance DetectableZero WordPtr+instance DetectableZero Fd+instance DetectableZero CRLim+instance DetectableZero CTcflag+instance DetectableZero CSpeed+instance DetectableZero CCc+instance DetectableZero CUid+instance DetectableZero CNlink+instance DetectableZero CGid+instance DetectableZero CSsize+instance DetectableZero CPid+instance DetectableZero COff+instance DetectableZero CMode+instance DetectableZero CIno+instance DetectableZero CDev+instance DetectableZero Natural+instance Integral a => DetectableZero (Ratio a)+deriving instance DetectableZero a => DetectableZero (Product a)+deriving instance DetectableZero a => DetectableZero (Sum a)+instance RealFloat a => DetectableZero (Complex a)+instance HasResolution a => DetectableZero (Fixed a)+deriving instance DetectableZero a => DetectableZero (Identity a)+ ------------------------------------------------------------------------ -- Very boring instances ------------------------------------------------------------------------  $(traverse semiringIns [2..9]) $(traverse starIns [2..9])+$(traverse zeroIns [2..9])
src/Data/Semiring/Infinite.hs view
@@ -32,11 +32,17 @@   positiveInfinity :: a   default positiveInfinity :: RealFloat a => a   positiveInfinity = 1/0+  isPositiveInfinity :: a -> Bool+  default isPositiveInfinity :: RealFloat a => a -> Bool+  isPositiveInfinity x = isInfinite x && x > 0  class HasNegativeInfinity a where   negativeInfinity :: a   default negativeInfinity :: RealFloat a => a   negativeInfinity = negate (1/0)+  isNegativeInfinity :: a -> Bool+  default isNegativeInfinity :: RealFloat a => a -> Bool+  isNegativeInfinity x = isInfinite x && x < 0  instance HasPositiveInfinity Double instance HasNegativeInfinity Double@@ -111,18 +117,26 @@ instance HasNegativeInfinity (NegativeInfinite a) where   {-# INLINE negativeInfinity #-}   negativeInfinity = NegativeInfinity+  isNegativeInfinity NegativeInfinity = True+  isNegativeInfinity _ = False  instance HasPositiveInfinity (PositiveInfinite a) where   {-# INLINE positiveInfinity #-}   positiveInfinity = PositiveInfinity+  isPositiveInfinity PositiveInfinity = True+  isPositiveInfinity _ = False  instance HasNegativeInfinity (Infinite a) where   {-# INLINE negativeInfinity #-}   negativeInfinity = Negative+  isNegativeInfinity Negative = True+  isNegativeInfinity _ = False  instance HasPositiveInfinity (Infinite a) where   {-# INLINE positiveInfinity #-}   positiveInfinity = Positive+  isPositiveInfinity Positive = True+  isPositiveInfinity _ = False  instance (Enum a, Bounded a, Eq a) => Enum (NegativeInfinite a) where   succ = foldr (const . pure . succ) (pure minBound)
src/Data/Semiring/Numeric.hs view
@@ -52,6 +52,8 @@   {-# INLINE zero #-}   {-# INLINE one #-} +instance (Bounded a, Ord a) => DetectableZero (Bottleneck a)+ -- | Positive numbers only. -- -- @('<+>') = 'gcd'@@ -62,7 +64,7 @@   { getDivision :: a   } deriving (Eq, Ord, Read, Show, Bounded, Generic, Generic1, Num              ,Enum, Typeable, Storable, Fractional, Real, RealFrac-             ,Functor, Foldable, Traversable)+             ,Functor, Foldable, Traversable,DetectableZero)  -- | Only expects positive numbers instance (Integral a, Semiring a) => Semiring (Division a) where@@ -100,6 +102,8 @@   {-# INLINE zero #-}   {-# INLINE one #-} +instance (Ord a, Num a) => DetectableZero (Łukasiewicz a)+ -- | <https://en.wikipedia.org/wiki/Semiring#cite_ref-droste_14-0 Wikipedia> -- has some information on this. Also -- <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.304.6152&rep=rep1&type=pdf this>@@ -113,7 +117,7 @@   { getViterbi :: a   } deriving (Eq, Ord, Read, Show, Bounded, Generic, Generic1, Num              ,Enum, Typeable, Storable, Fractional, Real, RealFrac-             ,Functor, Foldable, Traversable)+             ,Functor, Foldable, Traversable,DetectableZero)  instance (Ord a, Semiring a) => Semiring (Viterbi a) where   (<+>) = (coerce :: WrapBinary Viterbi a) max@@ -147,6 +151,9 @@   {-# INLINE zero #-}   {-# INLINE one #-} +instance (Floating a, HasPositiveInfinity a) => DetectableZero (Log a) where+  isZero (Log x) = isPositiveInfinity x+ newtype PosFrac a = PosFrac   { getPosFrac :: a   } deriving (Eq, Ord, Read, Show, Generic, Generic1, Num@@ -167,6 +174,8 @@   {-# INLINE zero #-}   {-# INLINE one #-} +instance (Eq a, Semiring a) => DetectableZero (PosFrac a)+ instance (Ord a, Fractional a, Semiring a, HasPositiveInfinity a) =>          StarSemiring (PosFrac a) where     star (PosFrac n)@@ -192,6 +201,8 @@   {-# INLINE (<.>) #-}   {-# INLINE zero #-}   {-# INLINE one #-}++instance (Eq a, Semiring a) => DetectableZero (PosInt a)  instance (Eq a, Semiring a, HasPositiveInfinity a) =>          StarSemiring (PosInt a) where
src/Data/Semiring/TH.hs view
@@ -41,3 +41,20 @@         ct = map (AppT c . VarT) names     InstanceD Nothing ct (AppT c $ foldl AppT (TupleT n) (map VarT names)) <$>         sequence [cmbN n "<+>", cmbN n "<.>", repN n "zero", repN n "one"]++zeroIns :: Int -> Q Dec+zeroIns n = do+    names <- replicateM n (newName "a")+    let c = ConT (mkName "DetectableZero")+        ct = map (AppT c . VarT) names+    InstanceD Nothing ct (AppT c $ foldl AppT (TupleT n) (map VarT names)) <$>+      sequence [andAll n]++andAll :: Int -> Q Dec+andAll n = do+  let f = VarE (mkName "&&")+  let isZ = VarE (mkName "isZero")+  xs <- replicateM n (newName "x")+  let args = [TupP (map VarP xs)]+      res = foldl1 (\a e -> AppE (AppE f a) e ) (map (AppE isZ . VarE) xs)+  return $ FunD (mkName "isZero") [Clause args (NormalB res) []]
src/Test/Semiring.hs view
@@ -23,12 +23,15 @@   , starLaw   , plusLaw   , starLaws-  , nearUnLaws   , nearTernaryLaws   , ordLaws+  , zeroLaw+  , zeroIsZero+  , zeroLaws+  , nearUnaryLaws   ) where -import           Data.Semiring   (Semiring (..), StarSemiring (..))+import           Data.Semiring   (Semiring (..), StarSemiring (..), DetectableZero(..))  -- | Plus is associative. plusAssoc :: (Eq a, Semiring a, Show a) => a -> a -> a -> Either String String@@ -165,15 +168,15 @@ unaryLaws :: (Eq a, Semiring a, Show a) => a -> Either String String unaryLaws x = fmap unlines (sequence [plusId x, mulId x, annihilate x]) -nearUnLaws :: (Eq a, Semiring a, Show a) => a -> Either String String-nearUnLaws = plusId+nearUnaryLaws :: (Eq a, Semiring a, Show a) => a -> Either String String+nearUnaryLaws x = fmap unlines (sequence [plusId x, annihilate x])  nearTernaryLaws :: (Eq a, Semiring a, Show a)             => a -> a -> a -> Either String String nearTernaryLaws x y z =   fmap unlines (sequence [ plusAssoc x y z                          , mulAssoc x y z-                         , mulDistribL x y z])+                         , mulDistribR x y z])  binaryLaws :: (Eq a, Semiring a, Show a)            => a -> a -> Either String String@@ -251,3 +254,33 @@  ordLaws :: (Ord a, Semiring a, Show a) => a -> a -> a -> Either String String ordLaws x y z = fmap unlines (sequence [ordAddLaw x y z, ordMulLaw x y z])+++zeroLaw :: (Eq a, DetectableZero a, Show a) => a -> Either String String+zeroLaw (x :: a) = if res then Right s else Left s where+  lhs_1 = x == zero+  lhs_2 = zero == x+  rhs = isZero x+  res = lhs_1 == rhs && lhs_2 == rhs+  s = unlines+    [ "zero law" ++ (if res then "" else " not") ++ " followed."+    , "    Law:"+    , "        x == zero = zero == x = isZero x"+    , "    x = " ++ show x+    , "    x == zero = " ++ show lhs_1+    , "    zero == x = " ++ show lhs_2+    , "    isZero x  = " ++ show rhs ]++zeroIsZero :: (DetectableZero a, Show a) => f a -> Either String String+zeroIsZero (_ :: f a) = if res then Right s else Left s where+  z = zero :: a+  res = isZero z+  s = unlines+    [ "zero is zero law" ++ (if res then "" else " not") ++ " followed."+    , "    Law:"+    , "        isZero zero = True"+    , "    zero = " ++ show z+    , "    isZero zero = " ++ show res ]++zeroLaws :: (DetectableZero a, Show a, Eq a) => a -> Either String String+zeroLaws x = zeroLaw x *> zeroIsZero [x]
test/Spec.hs view
@@ -36,18 +36,21 @@ main = do   putStrLn "Integer"   smallCheck 1000 (unaryLaws   :: UnaryLaws   Integer)+  smallCheck 1000 (zeroLaws    :: UnaryLaws   Integer)   smallCheck 100  (binaryLaws  :: BinaryLaws  Integer)   smallCheck 10   (ternaryLaws :: TernaryLaws Integer)   smallCheck 10   (ordLaws     :: TernaryLaws Integer)    putStrLn "(WordOfSize 2)"   smallCheck 16  (unaryLaws   :: UnaryLaws   (WordOfSize 2))+  smallCheck 16  (zeroLaws    :: UnaryLaws   (WordOfSize 2))   smallCheck 16  (binaryLaws  :: BinaryLaws  (WordOfSize 2))   smallCheck 16  (ternaryLaws :: TernaryLaws (WordOfSize 2))   smallCheck 16  (starLaws    :: UnaryLaws   (PositiveInfinite (WordOfSize 2)))    putStrLn "(WordOfSize 2,WordOfSize 2)"   smallCheck 16 (unaryLaws   :: UnaryLaws   (WordOfSize 2,WordOfSize 2))+  smallCheck 16 (zeroLaws    :: UnaryLaws   (WordOfSize 2,WordOfSize 2))   smallCheck 14 (binaryLaws  :: BinaryLaws  (WordOfSize 2,WordOfSize 2))   smallCheck 8  (ternaryLaws :: TernaryLaws (WordOfSize 2,WordOfSize 2))   smallCheck 16 (starLaws    :: UnaryLaws   (PositiveInfinite (WordOfSize 2)@@ -55,6 +58,7 @@    putStrLn "(WordOfSize 2,WordOfSize 2,WordOfSize 2)"   smallCheck 10 (unaryLaws   :: UnaryLaws   (WordOfSize 2,WordOfSize 2,WordOfSize 2))+  smallCheck 10 (zeroLaws    :: UnaryLaws   (WordOfSize 2,WordOfSize 2,WordOfSize 2))   smallCheck 5  (binaryLaws  :: BinaryLaws  (WordOfSize 2,WordOfSize 2,WordOfSize 2))   smallCheck 2  (ternaryLaws :: TernaryLaws (WordOfSize 2,WordOfSize 2,WordOfSize 2))   smallCheck 10 (starLaws    :: UnaryLaws   (PositiveInfinite (WordOfSize 2)@@ -63,6 +67,7 @@    putStrLn "(WordOfSize 2,WordOfSize 2,WordOfSize 2,WordOfSize 2)"   smallCheck 8 (unaryLaws   :: UnaryLaws   (WordOfSize 2,WordOfSize 2,WordOfSize 2,WordOfSize 2))+  smallCheck 8 (zeroLaws    :: UnaryLaws   (WordOfSize 2,WordOfSize 2,WordOfSize 2,WordOfSize 2))   smallCheck 4 (binaryLaws  :: BinaryLaws  (WordOfSize 2,WordOfSize 2,WordOfSize 2,WordOfSize 2))   smallCheck 1 (ternaryLaws :: TernaryLaws (WordOfSize 2,WordOfSize 2,WordOfSize 2,WordOfSize 2))   smallCheck 16 (starLaws    :: UnaryLaws   (PositiveInfinite (WordOfSize 2)@@ -72,6 +77,7 @@    putStrLn "(Int,Int,Int,Int,Int)"   quickCheck (unaryLaws   :: UnaryLaws   (Int,Int,Int,Int,Int))+  quickCheck (zeroLaws    :: UnaryLaws   (Int,Int,Int,Int,Int))   quickCheck (binaryLaws  :: BinaryLaws  (Int,Int,Int,Int,Int))   quickCheck (ternaryLaws :: TernaryLaws (Int,Int,Int,Int,Int))   quickCheck (starLaws    :: UnaryLaws   (PositiveInfinite Int@@ -82,6 +88,7 @@    putStrLn "(Int,Int,Int,Int,Int,Int)"   quickCheck (unaryLaws   :: UnaryLaws   (Int,Int,Int,Int,Int,Int))+  quickCheck (zeroLaws    :: UnaryLaws   (Int,Int,Int,Int,Int,Int))   quickCheck (binaryLaws  :: BinaryLaws  (Int,Int,Int,Int,Int,Int))   quickCheck (ternaryLaws :: TernaryLaws (Int,Int,Int,Int,Int,Int))   quickCheck (starLaws    :: UnaryLaws   (PositiveInfinite Int@@ -93,6 +100,7 @@    putStrLn "(Int,Int,Int,Int,Int,Int,Int)"   quickCheck (unaryLaws   :: UnaryLaws   (Int,Int,Int,Int,Int,Int,Int))+  quickCheck (zeroLaws    :: UnaryLaws   (Int,Int,Int,Int,Int,Int,Int))   quickCheck (binaryLaws  :: BinaryLaws  (Int,Int,Int,Int,Int,Int,Int))   quickCheck (ternaryLaws :: TernaryLaws (Int,Int,Int,Int,Int,Int,Int))   quickCheck (starLaws    :: UnaryLaws   (PositiveInfinite Int@@ -105,6 +113,7 @@    putStrLn "(Int,Int,Int,Int,Int,Int,Int,Int)"   quickCheck (unaryLaws   :: UnaryLaws   (Int,Int,Int,Int,Int,Int,Int,Int))+  quickCheck (zeroLaws    :: UnaryLaws   (Int,Int,Int,Int,Int,Int,Int,Int))   quickCheck (binaryLaws  :: BinaryLaws  (Int,Int,Int,Int,Int,Int,Int,Int))   quickCheck (ternaryLaws :: TernaryLaws (Int,Int,Int,Int,Int,Int,Int,Int))   quickCheck (starLaws    :: UnaryLaws   (PositiveInfinite Int@@ -118,6 +127,7 @@    putStrLn "(Int,Int,Int,Int,Int,Int,Int,Int,Int)"   quickCheck (unaryLaws   :: UnaryLaws   (Int,Int,Int,Int,Int,Int,Int,Int,Int))+  quickCheck (zeroLaws    :: UnaryLaws   (Int,Int,Int,Int,Int,Int,Int,Int,Int))   quickCheck (binaryLaws  :: BinaryLaws  (Int,Int,Int,Int,Int,Int,Int,Int,Int))   quickCheck (ternaryLaws :: TernaryLaws (Int,Int,Int,Int,Int,Int,Int,Int,Int))   quickCheck (starLaws    :: UnaryLaws   (PositiveInfinite Int@@ -132,51 +142,57 @@    putStrLn "Int"   smallCheck 1000 (unaryLaws   :: UnaryLaws   Int)+  smallCheck 1000 (zeroLaws    :: UnaryLaws   Int)   smallCheck 100  (binaryLaws  :: BinaryLaws  Int)   smallCheck 10   (ternaryLaws :: TernaryLaws Int)    putStrLn "PosInf Integer"-  smallCheck 1000 (nearUnLaws      :: UnaryLaws   (PositiveInfinite Integer))+  smallCheck 1000 (nearUnaryLaws   :: UnaryLaws   (PositiveInfinite Integer))   smallCheck 100  (binaryLaws      :: BinaryLaws  (PositiveInfinite Integer))-  smallCheck 10   (nearTernaryLaws :: TernaryLaws (PositiveInfinite Integer))-  smallCheck 10   (ordLaws         :: TernaryLaws (PositiveInfinite Integer))+  -- smallCheck 10   (nearTernaryLaws :: TernaryLaws (PositiveInfinite Integer))+  -- smallCheck 10   (ordLaws         :: TernaryLaws (PositiveInfinite Integer))    putStrLn "NegInf Integer"-  smallCheck 1000 (nearUnLaws      :: UnaryLaws   (NegativeInfinite Integer))+  smallCheck 1000 (nearUnaryLaws   :: UnaryLaws   (NegativeInfinite Integer))   smallCheck 100  (binaryLaws      :: BinaryLaws  (NegativeInfinite Integer))-  smallCheck 10   (nearTernaryLaws :: TernaryLaws (NegativeInfinite Integer))-  smallCheck 10   (ordLaws         :: TernaryLaws (NegativeInfinite Integer))+  -- smallCheck 10   (nearTernaryLaws :: TernaryLaws (NegativeInfinite Integer))+  -- smallCheck 10   (ordLaws         :: TernaryLaws (NegativeInfinite Integer)) -  -- putStrLn "Inf Integer"-  -- smallCheck 1000 (nearUnLaws      :: UnaryLaws   (Infinite Integer))-  -- smallCheck 100  (binaryLaws      :: BinaryLaws  (Infinite Integer))+  putStrLn "Inf Integer"+  smallCheck 1000 (nearUnaryLaws   :: UnaryLaws   (Infinite Integer))+  smallCheck 100  (binaryLaws      :: BinaryLaws  (Infinite Integer))   -- smallCheck 10   (nearTernaryLaws :: TernaryLaws (Infinite Integer))   -- smallCheck 10   (ordLaws         :: TernaryLaws (Infinite Integer))    putStrLn "()"   smallCheck 1 (unaryLaws   :: UnaryLaws   ())+  smallCheck 1 (zeroLaws    :: UnaryLaws   ())   smallCheck 1 (binaryLaws  :: BinaryLaws  ())   smallCheck 1 (ternaryLaws :: TernaryLaws ())   smallCheck 1 (starLaws    :: UnaryLaws   ())    putStrLn "Bool"   smallCheck 2 (unaryLaws   :: UnaryLaws   Bool)+  smallCheck 2 (zeroLaws    :: UnaryLaws   Bool)   smallCheck 4 (binaryLaws  :: BinaryLaws  Bool)   smallCheck 8 (ternaryLaws :: TernaryLaws Bool)   smallCheck 2 (starLaws    :: UnaryLaws   Bool)    putStrLn "Any"   smallCheck 2 (unLawsOn   Any :: UnaryLaws   Bool)+  smallCheck 2 (zeroLaws . Any :: UnaryLaws   Bool)   smallCheck 4 (binLawsOn  Any :: BinaryLaws  Bool)   smallCheck 8 (ternLawsOn Any :: TernaryLaws Bool)    putStrLn "All"   smallCheck 2 (unLawsOn   All :: UnaryLaws   Bool)+  smallCheck 2 (zeroLaws . All :: UnaryLaws   Bool)   smallCheck 4 (binLawsOn  All :: BinaryLaws  Bool)   smallCheck 8 (ternLawsOn All :: TernaryLaws Bool)    putStrLn "[WordOfSize 2]"   smallCheck 5 (unaryLaws   :: UnaryLaws   [WordOfSize 2])+  smallCheck 5 (zeroLaws    :: UnaryLaws   [WordOfSize 2])   smallCheck 4 (binaryLaws  :: BinaryLaws  [WordOfSize 2])   smallCheck 3 (ternaryLaws :: TernaryLaws [WordOfSize 2]) @@ -199,26 +215,31 @@    putStrLn "Bottleneck (WordOfSize 2)"   smallCheck 1000 (unLawsOn   Bottleneck :: UnaryLaws   (WordOfSize 2))+  smallCheck 1000 (zeroLaws . Bottleneck :: UnaryLaws   (WordOfSize 2))   smallCheck 100  (binLawsOn  Bottleneck :: BinaryLaws  (WordOfSize 2))   smallCheck 10   (ternLawsOn Bottleneck :: TernaryLaws (WordOfSize 2))    putStrLn "Division Integer"   smallCheck 1000 (unLawsOn   (Division . getPositive) :: UnaryLaws   (SC.Positive Integer))+  smallCheck 1000 (zeroLaws .  Division . getPositive  :: UnaryLaws   (SC.Positive Integer))   smallCheck 100  (binLawsOn  (Division . getPositive) :: BinaryLaws  (SC.Positive Integer))   smallCheck 10   (ternLawsOn (Division . getPositive) :: TernaryLaws (SC.Positive Integer))    putStrLn "Łukasiewicz Double"   smallCheck 1000 (unLawsOn   Łukasiewicz :: UnaryLaws   Fraction)+  smallCheck 1000 (zeroLaws . Łukasiewicz :: UnaryLaws   Fraction)   smallCheck 100  (binLawsOn  Łukasiewicz :: BinaryLaws  Fraction)   smallCheck 10   (ternLawsOn Łukasiewicz :: TernaryLaws Fraction)    putStrLn "Viterbi Double"   smallCheck 1000 (unLawsOn   Viterbi :: UnaryLaws   Fraction)+  smallCheck 1000 (zeroLaws . Viterbi :: UnaryLaws   Fraction)   smallCheck 100  (binLawsOn  Viterbi :: BinaryLaws  Fraction)   smallCheck 10   (ternLawsOn Viterbi :: TernaryLaws Fraction)    putStrLn "Log Double"   quickCheck (unLawsOn   Log :: UnaryLaws   (Approx Double))+  quickCheck (zeroLaws . Log :: UnaryLaws   (Approx Double))   quickCheck (binLawsOn  Log :: BinaryLaws  (Approx Double))   quickCheck (ternLawsOn Log :: TernaryLaws (Approx Double)) @@ -233,6 +254,7 @@    putStrLn "Endo (Add Bool)"   smallCheck 3 (unOn plusId        eFromFunc :: UnaryLaws   (Bool -> Bool))+  smallCheck 3 (zeroLaws .         eFromFunc :: UnaryLaws   (Bool -> Bool))   smallCheck 3 (unOn mulId         eFromFunc :: UnaryLaws   (Bool -> Bool))   smallCheck 2 (binLawsOn          eFromFunc :: BinaryLaws  (Bool -> Bool))   smallCheck 2 (ternOn plusAssoc   eFromFunc :: TernaryLaws (Bool -> Bool))@@ -278,6 +300,8 @@     Fraction Double     deriving (Show,Num,Fractional,Real,RealFrac,Floating,RealFloat,Semiring) +instance DetectableZero Fraction where isZero = (0==)+ newtype Approx a =     Approx a     deriving (Show,Num,Fractional,Real,RealFrac,Floating,RealFloat,Semiring@@ -322,6 +346,7 @@   arbitrary = arbitraryBoundedEnum  instance KnownNat n => Semiring (WordOfSize n)+instance KnownNat n => DetectableZero (WordOfSize n)  instance (Monad m, Serial m a) => Serial m (PositiveInfinite a) where   series = fmap (maybe PositiveInfinity PosFinite) series@@ -339,7 +364,7 @@ data Func a b = Func b (IntMap b)   deriving (Eq, Ord) -newtype EndoFunc a = EndoFunc (Endo a) deriving Semiring+newtype EndoFunc a = EndoFunc (Endo a) deriving (Semiring, DetectableZero)  instance (Enum a, Bounded a, Ord a) => Eq (EndoFunc a) where   EndoFunc (Endo f) == EndoFunc (Endo g) = fromFunc f == fromFunc g@@ -388,6 +413,8 @@   one = fromFunc one   f <+> g = fromFunc (apply f <+> apply g)   f <.> g = fromFunc (apply f <.> apply g)++  ------------------------------------------------------------------------ -- QuickCheck wrappers