From 9f988525f3067de0fb68ebababbdd54f06a2eaa2 Mon Sep 17 00:00:00 2001 From: David Feuer Date: Sat, 30 Oct 2021 19:38:35 -0400 Subject: Improve mtimesDefault * Make 'mtimesDefault' use 'stimes' for the underlying monoid rather than the default 'stimes'. * Explain in the documentation why one might use `mtimesDefault`. --- libraries/base/Data/Semigroup.hs | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) (limited to 'libraries/base') 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 -- cgit v1.2.1