Skip to content

Commit f853287

Browse files
authored
Merge pull request #50 from endgame/more-instances
MonoidNull: More instances
2 parents 1406acd + 23b2c0e commit f853287

File tree

2 files changed

+149
-7
lines changed

2 files changed

+149
-7
lines changed

CHANGELOG.md

+23
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,26 @@
1+
Unreleased (Minor)
2+
------------------
3+
4+
* `Data.Monoid.Null.MonoidNull` now has a default implementation
5+
* Add instances of `MonoidNull` and (where appropriate) `PositiveMonoid` for:
6+
- `(a, b, c, d, e)`
7+
- `Data.Functor.Compose f g a`
8+
- `Data.Functor.Const r a`
9+
- `Data.Functor.Identity a`
10+
- `Data.Functor.Product f g a`
11+
- `Data.Ord.Down a`
12+
- `Data.Proxy.Proxy a`
13+
- `Data.Semigroup.Max a`
14+
- `Data.Semigroup.Min a`
15+
- `Data.Semigroup.WrappedMonoid a`
16+
- `GHC.Generics.(:*:) f g a`
17+
- `GHC.Generics.(:.:) f g a`
18+
- `GHC.Generics.K1 i c p`
19+
- `GHC.Generics.M1 i c f p`
20+
- `GHC.Generics.Par1 p`
21+
- `GHC.Generics.Rec1 f p`
22+
- `GHC.Generics.U1 p`
23+
124
Version 1.2.4.1
225
---------------
326
* Bumped the `text` dependency upper bounds

src/Data/Monoid/Null.hs

+126-7
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,27 @@
1-
{-
1+
{-
22
Copyright 2013-2015 Mario Blazevic
33
44
License: BSD3 (see BSD3-LICENSE.txt file)
55
-}
66

77
-- | This module defines the MonoidNull class and some of its instances.
8-
--
8+
--
99

10-
{-# LANGUAGE Haskell2010, FlexibleInstances, Trustworthy #-}
10+
{-# LANGUAGE Haskell2010, CPP, FlexibleInstances, DefaultSignatures, Trustworthy #-}
1111

1212
module Data.Monoid.Null (
1313
MonoidNull(..), PositiveMonoid
1414
)
1515
where
16-
16+
17+
import Data.Functor.Compose (Compose(..))
18+
import Data.Functor.Const (Const(..))
19+
import Data.Functor.Identity (Identity(..))
1720
import Data.Monoid -- (Monoid, First(..), Last(..), Dual(..), Sum(..), Product(..), All(getAll), Any(getAny))
21+
import Data.Ord (Down(..))
22+
import Data.Proxy (Proxy)
23+
import Data.Semigroup (Max, Min, WrappedMonoid(..))
24+
import qualified Data.Functor.Product as Functor
1825
import qualified Data.List as List
1926
import qualified Data.ByteString as ByteString
2027
import qualified Data.ByteString.Lazy as LazyByteString
@@ -26,21 +33,24 @@ import qualified Data.Map as Map
2633
import qualified Data.Sequence as Sequence
2734
import qualified Data.Set as Set
2835
import qualified Data.Vector as Vector
36+
import GHC.Generics ((:*:)(..), (:.:)(..), K1(..), M1(..), Par1(..), Rec1(..), U1)
2937
import Numeric.Natural (Natural)
3038

3139
import Prelude hiding (null)
3240

3341
-- | Extension of 'Monoid' that allows testing a value for equality with 'mempty'. The following law must hold:
34-
--
42+
--
3543
-- prop> null x == (x == mempty)
36-
--
44+
--
3745
-- Furthermore, the performance of this method should be constant, /i.e./, independent of the length of its argument.
3846
class Monoid m => MonoidNull m where
3947
null :: m -> Bool
48+
default null :: Eq m => m -> Bool
49+
null = (==) mempty
4050

4151
-- | Subclass of 'Monoid' for types whose values have no inverse, with the exception of 'Data.Monoid.mempty'. More
4252
-- formally, the class instances must satisfy the following law:
43-
--
53+
--
4454
-- prop> null (x <> y) == (null x && null y)
4555
class MonoidNull m => PositiveMonoid m
4656

@@ -73,10 +83,78 @@ instance (Num a, Eq a) => MonoidNull (Sum a) where
7383
instance (Num a, Eq a) => MonoidNull (Product a) where
7484
null (Product a) = a == 1
7585

86+
-- | @since 1.2.5.0
87+
instance (Ord a, Bounded a) => MonoidNull (Max a)
88+
89+
-- | @since 1.2.5.0
90+
instance (Ord a, Bounded a) => MonoidNull (Min a)
91+
7692
instance Monoid a => MonoidNull (Maybe a) where
7793
null Nothing = True
7894
null _ = False
7995

96+
#if MIN_VERSION_base(4, 11, 0)
97+
-- | @since 1.2.5.0
98+
instance MonoidNull a => MonoidNull (Down a) where
99+
null (Down a) = null a
100+
#endif
101+
102+
#if MIN_VERSION_base(4, 12, 0)
103+
-- | @since 1.2.5.0
104+
instance MonoidNull c => MonoidNull (K1 i c p) where
105+
null (K1 c) = null c
106+
107+
-- | @since 1.2.5.0
108+
instance MonoidNull (f p) => MonoidNull (M1 i c f p) where
109+
null (M1 fp) = null fp
110+
111+
-- | @since 1.2.5.0
112+
instance MonoidNull p => MonoidNull (Par1 p) where
113+
null (Par1 p) = null p
114+
115+
-- | @since 1.2.5.0
116+
instance MonoidNull (f p) => MonoidNull (Rec1 f p) where
117+
null (Rec1 fp) = null fp
118+
119+
-- | @since 1.2.5.0
120+
instance MonoidNull (U1 p) where
121+
null _ = True
122+
123+
-- | @since 1.2.5.0
124+
instance (MonoidNull (f p), MonoidNull (g p)) => MonoidNull ((:*:) f g p) where
125+
null (fp :*: gp) = null fp && null gp
126+
127+
-- | @since 1.2.5.0
128+
instance (MonoidNull (f (g p))) => MonoidNull ((:.:) f g p) where
129+
null (Comp1 fgp) = null fgp
130+
#endif
131+
132+
#if MIN_VERSION_base(4, 16, 0)
133+
-- | @since 1.2.5.0
134+
instance MonoidNull (f (g a)) => MonoidNull (Compose f g a) where
135+
null (Compose fga) = null fga
136+
137+
-- | @since 1.2.5.0
138+
instance (MonoidNull (f a), MonoidNull (g a)) => MonoidNull (Functor.Product f g a) where
139+
null (Functor.Pair fa ga) = null fa && null ga
140+
#endif
141+
142+
-- | @since 1.2.5.0
143+
instance MonoidNull r => MonoidNull (Const r a) where
144+
null (Const r) = null r
145+
146+
-- | @since 1.2.5.0
147+
instance MonoidNull a => MonoidNull (Identity a) where
148+
null (Identity a) = null a
149+
150+
-- | @since 1.2.5.0
151+
instance MonoidNull a => MonoidNull (WrappedMonoid a) where
152+
null (WrapMonoid a) = null a
153+
154+
-- | @since 1.2.5.0
155+
instance MonoidNull (Proxy a) where
156+
null _ = True
157+
80158
instance (MonoidNull a, MonoidNull b) => MonoidNull (a, b) where
81159
null (a, b) = null a && null b
82160

@@ -86,6 +164,10 @@ instance (MonoidNull a, MonoidNull b, MonoidNull c) => MonoidNull (a, b, c) wher
86164
instance (MonoidNull a, MonoidNull b, MonoidNull c, MonoidNull d) => MonoidNull (a, b, c, d) where
87165
null (a, b, c, d) = null a && null b && null c && null d
88166

167+
-- | @since 1.2.5.0
168+
instance (MonoidNull a, MonoidNull b, MonoidNull c, MonoidNull d, MonoidNull e) => MonoidNull (a, b, c, d, e) where
169+
null (a, b, c, d, e) = null a && null b && null c && null d && null e
170+
89171
instance MonoidNull [x] where
90172
null = List.null
91173

@@ -133,6 +215,10 @@ instance PositiveMonoid Text.Text
133215
instance PositiveMonoid LazyText.Text
134216
instance PositiveMonoid (Product Natural)
135217
instance PositiveMonoid (Sum Natural)
218+
-- | @since 1.2.5.0
219+
instance (Ord a, Bounded a) => PositiveMonoid (Min a)
220+
-- | @since 1.2.5.0
221+
instance (Ord a, Bounded a) => PositiveMonoid (Max a)
136222
instance Monoid a => PositiveMonoid (Maybe a)
137223
instance PositiveMonoid (First a)
138224
instance PositiveMonoid (Last a)
@@ -144,6 +230,39 @@ instance PositiveMonoid IntSet.IntSet
144230
instance PositiveMonoid (Sequence.Seq a)
145231
instance Ord a => PositiveMonoid (Set.Set a)
146232
instance PositiveMonoid (Vector.Vector a)
233+
-- | @since 1.2.5.0
234+
instance PositiveMonoid r => PositiveMonoid (Const r a)
235+
-- | @since 1.2.5.0
236+
instance PositiveMonoid a => PositiveMonoid (Identity a)
237+
-- | @since 1.2.5.0
238+
instance PositiveMonoid a => PositiveMonoid (WrappedMonoid a)
239+
-- | @since 1.2.5.0
240+
instance PositiveMonoid (Proxy a)
241+
242+
#if MIN_VERSION_base(4, 11, 0)
243+
-- | @since 1.2.5.0
244+
instance PositiveMonoid a => PositiveMonoid (Down a)
245+
#endif
246+
247+
#if MIN_VERSION_base(4, 12, 0)
248+
-- | @since 1.2.5.0
249+
instance PositiveMonoid c => PositiveMonoid (K1 i c p)
250+
-- | @since 1.2.5.0
251+
instance PositiveMonoid (f p) => PositiveMonoid (M1 i c f p)
252+
-- | @since 1.2.5.0
253+
instance PositiveMonoid p => PositiveMonoid (Par1 p)
254+
-- | @since 1.2.5.0
255+
instance PositiveMonoid (f p) => PositiveMonoid (Rec1 f p)
256+
-- | @since 1.2.5.0
257+
instance PositiveMonoid (U1 p)
258+
-- | @since 1.2.5.0
259+
instance (PositiveMonoid (f (g p))) => PositiveMonoid ((:.:) f g p)
260+
#endif
261+
262+
#if MIN_VERSION_base(4, 16, 0)
263+
-- | @since 1.2.5.0
264+
instance PositiveMonoid (f (g a)) => PositiveMonoid (Compose f g a)
265+
#endif
147266

148267
-- The possible tuple instances would be overlapping, so we leave the choice to the user.
149268
--

0 commit comments

Comments
 (0)