summaryrefslogtreecommitdiff
path: root/libraries
diff options
context:
space:
mode:
authorDavid Feuer <David.Feuer@gmail.com>2021-10-30 19:38:35 -0400
committerAndreas Klebinger <klebinger.andreas@gmx.at>2021-12-09 13:49:47 +0000
commit9f988525f3067de0fb68ebababbdd54f06a2eaa2 (patch)
tree3b9dee1c3384ee61bb63a63572a9a5e4642ed254 /libraries
parentd6177cb5dac357ff15ae048556f03039dd6987d2 (diff)
downloadhaskell-9f988525f3067de0fb68ebababbdd54f06a2eaa2.tar.gz
Improve mtimesDefault
* Make 'mtimesDefault' use 'stimes' for the underlying monoid rather than the default 'stimes'. * Explain in the documentation why one might use `mtimesDefault`.
Diffstat (limited to 'libraries')
-rw-r--r--libraries/base/Data/Semigroup.hs25
1 files changed, 22 insertions, 3 deletions
diff --git a/libraries/base/Data/Semigroup.hs b/libraries/base/Data/Semigroup.hs
index d31e8ce073..08040dfea8 100644
--- a/libraries/base/Data/Semigroup.hs
+++ b/libraries/base/Data/Semigroup.hs
@@ -512,10 +512,29 @@ instance Enum a => Enum (WrappedMonoid a) where
--
-- > mtimesDefault n a = a <> a <> ... <> a -- using <> (n-1) times
--
--- Implemented using 'stimes' and 'mempty'.
+-- In many cases, `stimes 0 a` for a `Monoid` will produce `mempty`.
+-- However, there are situations when it cannot do so. In particular,
+-- the following situation is fairly common:
--
--- This is a suitable definition for an 'mtimes' member of 'Monoid'.
+-- @
+-- data T a = ...
+--
+-- class Constraint1 a
+-- class Constraint1 a => Constraint2 a
+--
+-- @
+-- instance Constraint1 a => 'Semigroup' (T a)
+-- instance Constraint2 a => 'Monoid' (T a)
+-- @
+--
+-- Since @Constraint1@ is insufficient to implement 'mempty',
+-- 'stimes' for @T a@ cannot do so.
+--
+-- When working with such a type, or when working polymorphically with
+-- 'Semigroup' instances, @mtimesDefault@ should be used when the
+-- multiplier might be zero. It is implemented using 'stimes' when
+-- the multiplier is nonzero and 'mempty' when it is zero.
mtimesDefault :: (Integral b, Monoid a) => b -> a -> a
mtimesDefault n x
| n == 0 = mempty
- | otherwise = unwrapMonoid (stimes n (WrapMonoid x))
+ | otherwise = stimes n x