summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabriella Gonzalez <Gabriel439@gmail.com>2022-07-24 12:54:21 -0700
committerMarge Bot <ben+marge-bot@smart-cactus.org>2022-07-25 09:42:40 -0400
commit2a773259fae8ae178a80538223b3e7a9bda93717 (patch)
tree7e584b3a56976de4174ba0ae087ffb6550557a30
parent918620d9e2f9e4a0122c57d7fdddbe34626f34b0 (diff)
downloadhaskell-2a773259fae8ae178a80538223b3e7a9bda93717.tar.gz
Default implementation for mempty/(<>)
Approved by: https://github.com/haskell/core-libraries-committee/issues/61 This adds a default implementation for `mempty` and `(<>)` along with a matching `MINIMAL` pragma so that `Semigroup` and `Monoid` instances can be defined in terms of `sconcat` / `mconcat`. The description for each class has also been updated to include the equivalent set of laws for the `sconcat`-only / `mconcat`-only instances.
-rw-r--r--libraries/base/GHC/Base.hs22
-rw-r--r--libraries/base/changelog.md2
2 files changed, 23 insertions, 1 deletions
diff --git a/libraries/base/GHC/Base.hs b/libraries/base/GHC/Base.hs
index 0ddd256426..c63ec1264f 100644
--- a/libraries/base/GHC/Base.hs
+++ b/libraries/base/GHC/Base.hs
@@ -211,6 +211,12 @@ infixr 6 <>
--
-- [Associativity] @x '<>' (y '<>' z) = (x '<>' y) '<>' z@
--
+-- You can alternatively define `sconcat` instead of (`<>`), in which case the
+-- laws are:
+--
+-- [Unit]: @'sconcat' ('pure' x) = x@
+-- [Multiplication]: @'sconcat' ('join' xss) = 'sconcat' ('fmap' 'sconcat' xss)@
+--
-- @since 4.9.0.0
class Semigroup a where
-- | An associative operation.
@@ -218,6 +224,7 @@ class Semigroup a where
-- >>> [1,2,3] <> [4,5,6]
-- [1,2,3,4,5,6]
(<>) :: a -> a -> a
+ a <> b = sconcat (a :| [ b ])
-- | Reduce a non-empty list with '<>'
--
@@ -248,6 +255,8 @@ class Semigroup a where
stimes :: Integral b => b -> a -> a
stimes = stimesDefault
+ {-# MINIMAL (<>) | sconcat #-}
+
-- | The class of monoids (types with an associative binary operation that
-- has an identity). Instances should satisfy the following:
@@ -257,6 +266,13 @@ class Semigroup a where
-- [Associativity] @x '<>' (y '<>' z) = (x '<>' y) '<>' z@ ('Semigroup' law)
-- [Concatenation] @'mconcat' = 'foldr' ('<>') 'mempty'@
--
+-- You can alternatively define `mconcat` instead of `mempty`, in which case the
+-- laws are:
+--
+-- [Unit]: @'mconcat' ('pure' x) = x@
+-- [Multiplication]: @'mconcat' ('join' xss) = 'mconcat' ('fmap' 'mconcat' xss)@
+-- [Subclass]: @'mconcat' ('toList' xs) = 'sconcat' xs@
+--
-- The method names refer to the monoid of lists under concatenation,
-- but there are many other instances.
--
@@ -271,7 +287,9 @@ class Semigroup a => Monoid a where
--
-- >>> "Hello world" <> mempty
-- "Hello world"
- mempty :: a
+ mempty :: a
+ mempty = mconcat []
+ {-# INLINE mempty #-}
-- | An associative operation
--
@@ -297,6 +315,8 @@ class Semigroup a => Monoid a where
{-# INLINE mconcat #-}
-- INLINE in the hope of fusion with mconcat's argument (see !4890)
+ {-# MINIMAL mempty | mconcat #-}
+
-- | @since 4.9.0.0
instance Semigroup [a] where
(<>) = (++)
diff --git a/libraries/base/changelog.md b/libraries/base/changelog.md
index adc18af65c..06570b5371 100644
--- a/libraries/base/changelog.md
+++ b/libraries/base/changelog.md
@@ -11,6 +11,8 @@
* Add `applyWhen` to `Data.Function`.
* Add functions `mapAccumM` and `forAccumM` to `Data.Traversable`, per the
[Core Libraries proposal](https://github.com/haskell/core-libraries-committee/issues/65).
+ * Add default implementation of `(<>)` in terms of `sconcat` and `mempty` in
+ terms of `mconcat`.
## 4.17.0.0 *TBA*