monoid-subclasses 1.2.4.1 → 1.2.5
raw patch · 5 files changed
+244/−12 lines, 5 filesdep ~commutative-semigroups
Dependency ranges changed: commutative-semigroups
Files
- CHANGELOG.md +26/−1
- Test/TestMonoidSubclasses.hs +15/−1
- monoid-subclasses.cabal +3/−3
- src/Data/Monoid/Null.hs +126/−7
- src/Data/Semigroup/Cancellative.hs +74/−0
CHANGELOG.md view
@@ -1,6 +1,31 @@+Version 1.2.5+---------------++* `Data.Monoid.Null.MonoidNull` now has a default implementation+* Add instances of `MonoidNull` and (where appropriate) `PositiveMonoid` for:+ - `(a, b, c, d, e)`+ - `Data.Functor.Compose f g a`+ - `Data.Functor.Const r a`+ - `Data.Functor.Identity a`+ - `Data.Functor.Product f g a`+ - `Data.Ord.Down a`+ - `Data.Proxy.Proxy a`+ - `Data.Semigroup.Max a`+ - `Data.Semigroup.Min a`+ - `Data.Semigroup.WrappedMonoid a`+ - `GHC.Generics.(:*:) f g a`+ - `GHC.Generics.(:.:) f g a`+ - `GHC.Generics.K1 i c p`+ - `GHC.Generics.M1 i c f p`+ - `GHC.Generics.Par1 p`+ - `GHC.Generics.Rec1 f p`+ - `GHC.Generics.U1 p`+* Added instances of `Reductive` for `Max a`, `Min a`, `Any`, and `All`+* Bumped the `commutative-semigroups` dependency upper bound+ Version 1.2.4.1 ----------------* Bumped the `text` dependency upper bounds+* Bumped the `text` dependency upper bound Version 1.2.4 ---------------
Test/TestMonoidSubclasses.hs view
@@ -23,6 +23,8 @@ import Control.Applicative (Applicative(..), liftA2) import Data.Functor ((<$>))+import Data.Functor.Const (Const(..))+import Data.Functor.Identity (Identity(..)) import Data.Foldable (foldMap, toList) import Data.Int (Int8, Int32) import qualified Data.Foldable as Foldable@@ -31,6 +33,7 @@ import qualified Data.List as List import Data.Maybe (isJust) import Data.Either (lefts, rights)+import Data.Proxy (Proxy) import Data.Tuple (swap) import Data.String (IsString, fromString) import Data.Char (isLetter)@@ -64,7 +67,7 @@ import Data.Monoid.Instances.Positioned (OffsetPositioned, LinePositioned) import qualified Data.Monoid.Instances.Positioned as Positioned -import Data.Semigroup (Semigroup, (<>))+import Data.Semigroup (Semigroup, (<>), Max, Min) import Data.Monoid (Monoid, mempty, mconcat, All(All), Any(Any), Dual(Dual), First(First), Last(Last), Sum(Sum), Product(Product)) import Data.Semigroup.Factorial (Factorial, StableFactorial, @@ -206,6 +209,11 @@ PositiveMonoidInstance (mempty :: Ordering), PositiveMonoidInstance (mempty :: All), PositiveMonoidInstance (mempty :: Any),+ PositiveMonoidInstance (mempty :: Max Int),+ PositiveMonoidInstance (mempty :: Min Int),+ PositiveMonoidInstance (mempty :: Const String Float),+ PositiveMonoidInstance (mempty :: Identity Ordering),+ PositiveMonoidInstance (mempty :: (Proxy Float)), PositiveMonoidInstance (mempty :: (Maybe (Sum Integer))), PositiveMonoidInstance (mempty :: (Product Natural)), PositiveMonoidInstance (mempty :: (Sum Natural)),@@ -317,6 +325,12 @@ reductiveInstances = map upcast cancellativeInstances ++ [ReductiveMonoidInstance (mempty :: Product Integer),+ ReductiveMonoidInstance (mempty :: Max Int),+ ReductiveMonoidInstance (mempty :: Min Int),+ ReductiveMonoidInstance (mempty :: All),+ ReductiveMonoidInstance (mempty :: Any),+ ReductiveMonoidInstance (mempty :: Identity IntSet),+ ReductiveMonoidInstance (mempty :: Const (Sum Int) Float), ReductiveMonoidInstance (mempty :: IntSet), ReductiveMonoidInstance (mempty :: Maybe IntSet), ReductiveMonoidInstance (mempty :: Set Integer)]
monoid-subclasses.cabal view
@@ -1,5 +1,5 @@ Name: monoid-subclasses-Version: 1.2.4.1+Version: 1.2.5 Cabal-Version: >= 1.10 Build-Type: Simple Synopsis: Subclasses of Monoid@@ -11,7 +11,7 @@ License: BSD3 License-file: BSD3-LICENSE.txt-Copyright: (c) 2013-2023 Mario Blažević+Copyright: (c) 2013-2024 Mario Blažević Author: Mario Blažević Maintainer: Mario Blažević <blamario@protonmail.com> Homepage: https://github.com/blamario/monoid-subclasses/@@ -46,7 +46,7 @@ text >= 0.11 && < 1.3 || >= 2.0 && < 2.2, primes == 0.2.*, vector >= 0.12 && < 0.14,- commutative-semigroups >= 0.1 && < 0.2+ commutative-semigroups >= 0.1 && < 0.3 GHC-options: -Wall default-language: Haskell2010
src/Data/Monoid/Null.hs view
@@ -1,20 +1,27 @@-{- +{- Copyright 2013-2015 Mario Blazevic License: BSD3 (see BSD3-LICENSE.txt file) -} -- | This module defines the MonoidNull class and some of its instances.--- +-- -{-# LANGUAGE Haskell2010, FlexibleInstances, Trustworthy #-}+{-# LANGUAGE Haskell2010, CPP, FlexibleInstances, DefaultSignatures, Trustworthy #-} module Data.Monoid.Null ( MonoidNull(..), PositiveMonoid ) where- ++import Data.Functor.Compose (Compose(..))+import Data.Functor.Const (Const(..))+import Data.Functor.Identity (Identity(..)) import Data.Monoid -- (Monoid, First(..), Last(..), Dual(..), Sum(..), Product(..), All(getAll), Any(getAny))+import Data.Ord (Down(..))+import Data.Proxy (Proxy)+import Data.Semigroup (Max, Min, WrappedMonoid(..))+import qualified Data.Functor.Product as Functor import qualified Data.List as List import qualified Data.ByteString as ByteString import qualified Data.ByteString.Lazy as LazyByteString@@ -26,21 +33,24 @@ import qualified Data.Sequence as Sequence import qualified Data.Set as Set import qualified Data.Vector as Vector+import GHC.Generics ((:*:)(..), (:.:)(..), K1(..), M1(..), Par1(..), Rec1(..), U1) import Numeric.Natural (Natural) import Prelude hiding (null) -- | Extension of 'Monoid' that allows testing a value for equality with 'mempty'. The following law must hold:--- +-- -- prop> null x == (x == mempty)--- +-- -- Furthermore, the performance of this method should be constant, /i.e./, independent of the length of its argument. class Monoid m => MonoidNull m where null :: m -> Bool+ default null :: Eq m => m -> Bool+ null = (==) mempty -- | Subclass of 'Monoid' for types whose values have no inverse, with the exception of 'Data.Monoid.mempty'. More -- formally, the class instances must satisfy the following law:--- +-- -- prop> null (x <> y) == (null x && null y) class MonoidNull m => PositiveMonoid m @@ -73,10 +83,78 @@ instance (Num a, Eq a) => MonoidNull (Product a) where null (Product a) = a == 1 +-- | @since 1.2.5.0+instance (Ord a, Bounded a) => MonoidNull (Max a)++-- | @since 1.2.5.0+instance (Ord a, Bounded a) => MonoidNull (Min a)+ instance Monoid a => MonoidNull (Maybe a) where null Nothing = True null _ = False +#if MIN_VERSION_base(4, 11, 0)+-- | @since 1.2.5.0+instance MonoidNull a => MonoidNull (Down a) where+ null (Down a) = null a+#endif++#if MIN_VERSION_base(4, 12, 0)+-- | @since 1.2.5.0+instance MonoidNull c => MonoidNull (K1 i c p) where+ null (K1 c) = null c++-- | @since 1.2.5.0+instance MonoidNull (f p) => MonoidNull (M1 i c f p) where+ null (M1 fp) = null fp++-- | @since 1.2.5.0+instance MonoidNull p => MonoidNull (Par1 p) where+ null (Par1 p) = null p++-- | @since 1.2.5.0+instance MonoidNull (f p) => MonoidNull (Rec1 f p) where+ null (Rec1 fp) = null fp++-- | @since 1.2.5.0+instance MonoidNull (U1 p) where+ null _ = True++-- | @since 1.2.5.0+instance (MonoidNull (f p), MonoidNull (g p)) => MonoidNull ((:*:) f g p) where+ null (fp :*: gp) = null fp && null gp++-- | @since 1.2.5.0+instance (MonoidNull (f (g p))) => MonoidNull ((:.:) f g p) where+ null (Comp1 fgp) = null fgp+#endif++#if MIN_VERSION_base(4, 16, 0)+-- | @since 1.2.5.0+instance MonoidNull (f (g a)) => MonoidNull (Compose f g a) where+ null (Compose fga) = null fga++-- | @since 1.2.5.0+instance (MonoidNull (f a), MonoidNull (g a)) => MonoidNull (Functor.Product f g a) where+ null (Functor.Pair fa ga) = null fa && null ga+#endif++-- | @since 1.2.5.0+instance MonoidNull r => MonoidNull (Const r a) where+ null (Const r) = null r++-- | @since 1.2.5.0+instance MonoidNull a => MonoidNull (Identity a) where+ null (Identity a) = null a++-- | @since 1.2.5.0+instance MonoidNull a => MonoidNull (WrappedMonoid a) where+ null (WrapMonoid a) = null a++-- | @since 1.2.5.0+instance MonoidNull (Proxy a) where+ null _ = True+ instance (MonoidNull a, MonoidNull b) => MonoidNull (a, b) where null (a, b) = null a && null b @@ -86,6 +164,10 @@ instance (MonoidNull a, MonoidNull b, MonoidNull c, MonoidNull d) => MonoidNull (a, b, c, d) where null (a, b, c, d) = null a && null b && null c && null d +-- | @since 1.2.5.0+instance (MonoidNull a, MonoidNull b, MonoidNull c, MonoidNull d, MonoidNull e) => MonoidNull (a, b, c, d, e) where+ null (a, b, c, d, e) = null a && null b && null c && null d && null e+ instance MonoidNull [x] where null = List.null @@ -133,6 +215,10 @@ instance PositiveMonoid LazyText.Text instance PositiveMonoid (Product Natural) instance PositiveMonoid (Sum Natural)+-- | @since 1.2.5.0+instance (Ord a, Bounded a) => PositiveMonoid (Min a)+-- | @since 1.2.5.0+instance (Ord a, Bounded a) => PositiveMonoid (Max a) instance Monoid a => PositiveMonoid (Maybe a) instance PositiveMonoid (First a) instance PositiveMonoid (Last a)@@ -144,6 +230,39 @@ instance PositiveMonoid (Sequence.Seq a) instance Ord a => PositiveMonoid (Set.Set a) instance PositiveMonoid (Vector.Vector a)+-- | @since 1.2.5.0+instance PositiveMonoid r => PositiveMonoid (Const r a)+-- | @since 1.2.5.0+instance PositiveMonoid a => PositiveMonoid (Identity a)+-- | @since 1.2.5.0+instance PositiveMonoid a => PositiveMonoid (WrappedMonoid a)+-- | @since 1.2.5.0+instance PositiveMonoid (Proxy a)++#if MIN_VERSION_base(4, 11, 0)+-- | @since 1.2.5.0+instance PositiveMonoid a => PositiveMonoid (Down a)+#endif++#if MIN_VERSION_base(4, 12, 0)+-- | @since 1.2.5.0+instance PositiveMonoid c => PositiveMonoid (K1 i c p)+-- | @since 1.2.5.0+instance PositiveMonoid (f p) => PositiveMonoid (M1 i c f p)+-- | @since 1.2.5.0+instance PositiveMonoid p => PositiveMonoid (Par1 p)+-- | @since 1.2.5.0+instance PositiveMonoid (f p) => PositiveMonoid (Rec1 f p)+-- | @since 1.2.5.0+instance PositiveMonoid (U1 p)+-- | @since 1.2.5.0+instance (PositiveMonoid (f (g p))) => PositiveMonoid ((:.:) f g p)+#endif++#if MIN_VERSION_base(4, 16, 0)+-- | @since 1.2.5.0+instance PositiveMonoid (f (g a)) => PositiveMonoid (Compose f g a)+#endif -- The possible tuple instances would be overlapping, so we leave the choice to the user. --
src/Data/Semigroup/Cancellative.hs view
@@ -37,6 +37,8 @@ ) where +import Data.Functor.Const+import Data.Functor.Identity import Data.Semigroup -- (Semigroup, Dual(..), Sum(..), Product(..)) import Data.Semigroup.Commutative import qualified Data.List as List@@ -201,6 +203,78 @@ instance (CommutativeProduct a, Integral a) => RightReductive (Product a) where stripSuffix a b = b </> a++-- Max & Min instances++instance Ord a => Reductive (Max a) where+ a </> b = if b <= a then Just a else Nothing+instance Ord a => Reductive (Min a) where+ a </> b = if a <= b then Just a else Nothing++instance Ord a => LeftReductive (Max a) where+ isPrefixOf a b = a <= b+ stripPrefix a b = b </> a+instance Ord a => LeftReductive (Min a) where+ isPrefixOf a b = b <= a+ stripPrefix a b = b </> a++instance Ord a => RightReductive (Max a) where+ isSuffixOf a b = a <= b+ stripSuffix a b = b </> a+instance Ord a => RightReductive (Min a) where+ isSuffixOf a b = b <= a+ stripSuffix a b = b </> a++-- Any & All instances++instance Reductive Any where+ a </> b = if b <= a then Just a else Nothing+instance Reductive All where+ a </> b = if a <= b then Just a else Nothing++instance LeftReductive Any where+ isPrefixOf a b = a <= b+ stripPrefix a b = b </> a+instance LeftReductive All where+ isPrefixOf a b = b <= a+ stripPrefix a b = b </> a++instance RightReductive Any where+ isSuffixOf a b = a <= b+ stripSuffix a b = b </> a+instance RightReductive All where+ isSuffixOf a b = b <= a+ stripSuffix a b = b </> a++-- Identity & Const instances++instance Reductive a => Reductive (Identity a) where+ Identity a </> Identity b = Identity <$> (a </> b)+instance Reductive a => Reductive (Const a x) where+ Const a </> Const b = Const <$> (a </> b)++instance Cancellative a => Cancellative (Identity a)+instance Cancellative a => Cancellative (Const a x)++instance LeftReductive a => LeftReductive (Identity a) where+ stripPrefix (Identity a) (Identity b) = Identity <$> stripPrefix a b+ isPrefixOf (Identity a) (Identity b) = isPrefixOf a b+instance LeftReductive a => LeftReductive (Const a x) where+ stripPrefix (Const a) (Const b) = Const <$> stripPrefix a b+ isPrefixOf (Const a) (Const b) = isPrefixOf a b++instance RightReductive a => RightReductive (Identity a) where+ stripSuffix (Identity a) (Identity b) = Identity <$> stripSuffix a b+ isSuffixOf (Identity a) (Identity b) = isSuffixOf a b+instance RightReductive a => RightReductive (Const a x) where+ stripSuffix (Const a) (Const b) = Const <$> stripSuffix a b+ isSuffixOf (Const a) (Const b) = isSuffixOf a b++instance LeftCancellative a => LeftCancellative (Identity a)+instance LeftCancellative a => LeftCancellative (Const a x)++instance RightCancellative a => RightCancellative (Identity a)+instance RightCancellative a => RightCancellative (Const a x) -- Pair instances