base-4.20.0.0: src/Data/Semigroup.hs
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE Trustworthy #-}
-----------------------------------------------------------------------------
-- |
-- Module : Data.Semigroup
-- Copyright : (C) 2011-2015 Edward Kmett
-- License : BSD-style (see the file LICENSE)
--
-- Maintainer : libraries@haskell.org
-- Stability : provisional
-- Portability : portable
--
-- A type @a@ is a 'Semigroup' if it provides an associative function ('<>')
-- that lets you combine any two values of type @a@ into one. Where being
-- associative means that the following must always hold:
--
-- prop> (a <> b) <> c == a <> (b <> c)
--
-- ==== __Examples__
--
-- The 'Min' 'Semigroup' instance for 'Int' is defined to always pick the smaller
-- number:
--
-- >>> Min 1 <> Min 2 <> Min 3 <> Min 4 :: Min Int
-- Min {getMin = 1}
--
-- If we need to combine multiple values we can use the 'sconcat' function
-- to do so. We need to ensure however that we have at least one value to
-- operate on, since otherwise our result would be undefined. It is for this
-- reason that 'sconcat' uses "Data.List.NonEmpty.NonEmpty" - a list that
-- can never be empty:
--
-- >>> (1 :| [])
-- 1 :| [] -- equivalent to [1] but guaranteed to be non-empty.
--
-- >>> (1 :| [2, 3, 4])
-- 1 :| [2,3,4] -- equivalent to [1,2,3,4] but guaranteed to be non-empty.
--
-- Equipped with this guaranteed to be non-empty data structure, we can combine
-- values using 'sconcat' and a 'Semigroup' of our choosing. We can try the 'Min'
-- and 'Max' instances of 'Int' which pick the smallest, or largest number
-- respectively:
--
-- >>> sconcat (1 :| [2, 3, 4]) :: Min Int
-- Min {getMin = 1}
--
-- >>> sconcat (1 :| [2, 3, 4]) :: Max Int
-- Max {getMax = 4}
--
-- String concatenation is another example of a 'Semigroup' instance:
--
-- >>> "foo" <> "bar"
-- "foobar"
--
-- A 'Semigroup' is a generalization of a 'Monoid'. Yet unlike the 'Semigroup', the 'Monoid'
-- requires the presence of a neutral element ('mempty') in addition to the associative
-- operator. The requirement for a neutral element prevents many types from being a full Monoid,
-- like "Data.List.NonEmpty.NonEmpty".
--
-- Note that the use of @(\<\>)@ in this module conflicts with an operator with the same
-- name that is being exported by "Data.Monoid". However, this package
-- re-exports (most of) the contents of Data.Monoid, so to use semigroups
-- and monoids in the same package just
--
-- > import Data.Semigroup
--
-- @since 4.9.0.0
----------------------------------------------------------------------------
module Data.Semigroup (
Semigroup(..)
, stimesMonoid
, stimesIdempotent
, stimesIdempotentMonoid
, mtimesDefault
-- * Semigroups
, Min(..)
, Max(..)
, First(..)
, Last(..)
, WrappedMonoid(..)
-- * Re-exported monoids from GHC.Internal.Data.Monoid
, Dual(..)
, Endo(..)
, All(..)
, Any(..)
, Sum(..)
, Product(..)
-- * Difference lists of a semigroup
, diff
, cycle1
-- * ArgMin, ArgMax
, Arg(..)
, ArgMin
, ArgMax
) where
import GHC.Internal.Base hiding (Any)
import GHC.Internal.Enum
import GHC.Internal.Show
import GHC.Internal.Read
import GHC.Internal.Num
import GHC.Internal.Real
import GHC.Internal.Data.Functor ((<$>))
import Data.Bifoldable
import Data.Bifunctor
import Data.Bitraversable
import GHC.Internal.Data.Foldable
import GHC.Internal.Data.Traversable
import GHC.Internal.Data.Semigroup.Internal
import GHC.Internal.Control.Monad.Fix
import GHC.Internal.Data.Data
import GHC.Generics
import qualified GHC.Internal.List as List
-- $setup
-- >>> import Prelude
-- >>> import Data.List.NonEmpty (NonEmpty (..))
-- | A generalization of 'GHC.Internal.Data.List.cycle' to an arbitrary 'Semigroup'.
-- May fail to terminate for some values in some semigroups.
--
-- ==== __Examples__
--
-- >>> take 10 $ cycle1 [1, 2, 3]
-- [1,2,3,1,2,3,1,2,3,1]
--
-- >>> cycle1 (Right 1)
-- Right 1
--
-- >>> cycle1 (Left 1)
-- * hangs forever *
cycle1 :: Semigroup m => m -> m
cycle1 xs = xs' where xs' = xs <> xs'
-- | This lets you use a difference list of a 'Semigroup' as a 'Monoid'.
--
-- ==== __Examples__
--
-- > let hello = diff "Hello, "
--
-- >>> appEndo hello "World!"
-- "Hello, World!"
--
-- >>> appEndo (hello <> mempty) "World!"
-- "Hello, World!"
--
-- >>> appEndo (mempty <> hello) "World!"
-- "Hello, World!"
--
-- > let world = diff "World"
-- > let excl = diff "!"
--
-- >>> appEndo (hello <> (world <> excl)) mempty
-- "Hello, World!"
--
-- >>> appEndo ((hello <> world) <> excl) mempty
-- "Hello, World!"
diff :: Semigroup m => m -> Endo m
diff = Endo . (<>)
-- | The 'Min' 'Monoid' and 'Semigroup' always choose the smaller element as
-- by the 'Ord' instance and 'min' of the contained type.
--
-- ==== __Examples__
--
-- >>> Min 42 <> Min 3
-- Min 3
--
-- >>> sconcat $ Min 1 :| [ Min n | n <- [2 .. 100]]
-- Min {getMin = 1}
newtype Min a = Min { getMin :: a }
deriving ( Bounded -- ^ @since 4.9.0.0
, Eq -- ^ @since 4.9.0.0
, Ord -- ^ @since 4.9.0.0
, Show -- ^ @since 4.9.0.0
, Read -- ^ @since 4.9.0.0
, Data -- ^ @since 4.9.0.0
, Generic -- ^ @since 4.9.0.0
, Generic1 -- ^ @since 4.9.0.0
)
-- | @since 4.9.0.0
instance Enum a => Enum (Min a) where
succ (Min a) = Min (succ a)
pred (Min a) = Min (pred a)
toEnum = Min . toEnum
fromEnum = fromEnum . getMin
enumFrom (Min a) = Min `fmap` enumFrom a
enumFromThen (Min a) (Min b) = Min `fmap` enumFromThen a b
enumFromTo (Min a) (Min b) = Min `fmap` enumFromTo a b
enumFromThenTo (Min a) (Min b) (Min c) = Min `fmap` enumFromThenTo a b c
-- | @since 4.9.0.0
instance Ord a => Semigroup (Min a) where
(<>) = coerce (min :: a -> a -> a)
stimes = stimesIdempotent
-- | @since 4.9.0.0
instance (Ord a, Bounded a) => Monoid (Min a) where
mempty = maxBound
-- By default, we would get a lazy right fold. This forces the use of a strict
-- left fold instead.
mconcat = List.foldl' (<>) mempty
{-# INLINE mconcat #-}
-- | @since 4.9.0.0
instance Functor Min where
fmap f (Min x) = Min (f x)
-- | @since 4.9.0.0
instance Foldable Min where
foldMap f (Min a) = f a
-- | @since 4.9.0.0
instance Traversable Min where
traverse f (Min a) = Min `fmap` f a
-- | @since 4.9.0.0
instance Applicative Min where
pure = Min
a <* _ = a
_ *> a = a
(<*>) = coerce
liftA2 = coerce
-- | @since 4.9.0.0
instance Monad Min where
(>>) = (*>)
Min a >>= f = f a
-- | @since 4.9.0.0
instance MonadFix Min where
mfix f = fix (f . getMin)
-- | @since 4.9.0.0
instance Num a => Num (Min a) where
(Min a) + (Min b) = Min (a + b)
(Min a) * (Min b) = Min (a * b)
(Min a) - (Min b) = Min (a - b)
negate (Min a) = Min (negate a)
abs (Min a) = Min (abs a)
signum (Min a) = Min (signum a)
fromInteger = Min . fromInteger
-- | The 'Max' 'Monoid' and 'Semigroup' always choose the bigger element as
-- by the 'Ord' instance and 'max' of the contained type.
--
-- ==== __Examples__
--
-- >>> Max 42 <> Max 3
-- Max 42
--
-- >>> sconcat $ Max 1 :| [ Max n | n <- [2 .. 100]]
-- Max {getMax = 100}
newtype Max a = Max { getMax :: a }
deriving ( Bounded -- ^ @since 4.9.0.0
, Eq -- ^ @since 4.9.0.0
, Ord -- ^ @since 4.9.0.0
, Show -- ^ @since 4.9.0.0
, Read -- ^ @since 4.9.0.0
, Data -- ^ @since 4.9.0.0
, Generic -- ^ @since 4.9.0.0
, Generic1 -- ^ @since 4.9.0.0
)
-- | @since 4.9.0.0
instance Enum a => Enum (Max a) where
succ (Max a) = Max (succ a)
pred (Max a) = Max (pred a)
toEnum = Max . toEnum
fromEnum = fromEnum . getMax
enumFrom (Max a) = Max `fmap` enumFrom a
enumFromThen (Max a) (Max b) = Max `fmap` enumFromThen a b
enumFromTo (Max a) (Max b) = Max `fmap` enumFromTo a b
enumFromThenTo (Max a) (Max b) (Max c) = Max `fmap` enumFromThenTo a b c
-- | @since 4.9.0.0
instance Ord a => Semigroup (Max a) where
(<>) = coerce (max :: a -> a -> a)
stimes = stimesIdempotent
-- | @since 4.9.0.0
instance (Ord a, Bounded a) => Monoid (Max a) where
mempty = minBound
-- By default, we would get a lazy right fold. This forces the use of a strict
-- left fold instead.
mconcat = List.foldl' (<>) mempty
{-# INLINE mconcat #-}
-- | @since 4.9.0.0
instance Functor Max where
fmap f (Max x) = Max (f x)
-- | @since 4.9.0.0
instance Foldable Max where
foldMap f (Max a) = f a
-- | @since 4.9.0.0
instance Traversable Max where
traverse f (Max a) = Max `fmap` f a
-- | @since 4.9.0.0
instance Applicative Max where
pure = Max
a <* _ = a
_ *> a = a
(<*>) = coerce
liftA2 = coerce
-- | @since 4.9.0.0
instance Monad Max where
(>>) = (*>)
Max a >>= f = f a
-- | @since 4.9.0.0
instance MonadFix Max where
mfix f = fix (f . getMax)
-- | @since 4.9.0.0
instance Num a => Num (Max a) where
(Max a) + (Max b) = Max (a + b)
(Max a) * (Max b) = Max (a * b)
(Max a) - (Max b) = Max (a - b)
negate (Max a) = Max (negate a)
abs (Max a) = Max (abs a)
signum (Max a) = Max (signum a)
fromInteger = Max . fromInteger
-- | 'Arg' isn't itself a 'Semigroup' in its own right, but it can be
-- placed inside 'Min' and 'Max' to compute an arg min or arg max.
--
-- ==== __Examples__
--
-- >>> minimum [ Arg (x * x) x | x <- [-10 .. 10] ]
-- Arg 0 0
--
-- >>> maximum [ Arg (-0.2*x^2 + 1.5*x + 1) x | x <- [-10 .. 10] ]
-- Arg 3.8 4.0
--
-- >>> minimum [ Arg (-0.2*x^2 + 1.5*x + 1) x | x <- [-10 .. 10] ]
-- Arg (-34.0) (-10.0)
data Arg a b = Arg
a
-- ^ The argument used for comparisons in 'Eq' and 'Ord'.
b
-- ^ The "value" exposed via the 'Functor', 'Foldable' etc. instances.
deriving
( Show -- ^ @since 4.9.0.0
, Read -- ^ @since 4.9.0.0
, Data -- ^ @since 4.9.0.0
, Generic -- ^ @since 4.9.0.0
, Generic1 -- ^ @since 4.9.0.0
)
-- |
-- ==== __Examples__
--
-- >>> Min (Arg 0 ()) <> Min (Arg 1 ())
-- Min {getMin = Arg 0 ()}
--
-- >>> minimum [ Arg (length name) name | name <- ["violencia", "lea", "pixie"]]
-- Arg 3 "lea"
type ArgMin a b = Min (Arg a b)
-- |
-- ==== __Examples__
--
-- >>> Max (Arg 0 ()) <> Max (Arg 1 ())
-- Max {getMax = Arg 1 ()}
--
-- >>> maximum [ Arg (length name) name | name <- ["violencia", "lea", "pixie"]]
-- Arg 9 "violencia"
type ArgMax a b = Max (Arg a b)
-- | @since 4.9.0.0
instance Functor (Arg a) where
fmap f (Arg x a) = Arg x (f a)
-- | @since 4.9.0.0
instance Foldable (Arg a) where
foldMap f (Arg _ a) = f a
-- | @since 4.9.0.0
instance Traversable (Arg a) where
traverse f (Arg x a) = Arg x `fmap` f a
-- | @since 4.9.0.0
instance Eq a => Eq (Arg a b) where
Arg a _ == Arg b _ = a == b
-- | @since 4.9.0.0
instance Ord a => Ord (Arg a b) where
Arg a _ `compare` Arg b _ = compare a b
min x@(Arg a _) y@(Arg b _)
| a <= b = x
| otherwise = y
max x@(Arg a _) y@(Arg b _)
| a >= b = x
| otherwise = y
-- | @since 4.9.0.0
instance Bifunctor Arg where
bimap f g (Arg a b) = Arg (f a) (g b)
-- | @since 4.10.0.0
instance Bitraversable Arg where
bitraverse f g (Arg a b) = Arg <$> f a <*> g b
-- | @since 4.10.0.0
instance Bifoldable Arg where
bifoldMap f g (Arg a b) = f a <> g b
-- |
-- Beware that @Data.Semigroup.@'First' is different from
-- @Data.Monoid.@'Data.Monoid.First'. The former simply returns the first value,
-- so @Data.Semigroup.First Nothing <> x = Data.Semigroup.First Nothing@.
-- The latter returns the first non-'Nothing',
-- thus @Data.Monoid.First Nothing <> x = x@.
--
-- ==== __Examples__
--
-- >>> First 0 <> First 10
-- First 0
--
-- >>> sconcat $ First 1 :| [ First n | n <- [2 ..] ]
-- First 1
newtype First a = First { getFirst :: a }
deriving ( Bounded -- ^ @since 4.9.0.0
, Eq -- ^ @since 4.9.0.0
, Ord -- ^ @since 4.9.0.0
, Show -- ^ @since 4.9.0.0
, Read -- ^ @since 4.9.0.0
, Data -- ^ @since 4.9.0.0
, Generic -- ^ @since 4.9.0.0
, Generic1 -- ^ @since 4.9.0.0
)
-- | @since 4.9.0.0
instance Enum a => Enum (First a) where
succ (First a) = First (succ a)
pred (First a) = First (pred a)
toEnum = First . toEnum
fromEnum = fromEnum . getFirst
enumFrom (First a) = First `fmap` enumFrom a
enumFromThen (First a) (First b) = First `fmap` enumFromThen a b
enumFromTo (First a) (First b) = First `fmap` enumFromTo a b
enumFromThenTo (First a) (First b) (First c) = First `fmap` enumFromThenTo a b c
-- | @since 4.9.0.0
instance Semigroup (First a) where
a <> _ = a
stimes = stimesIdempotent
sconcat (x :| _) = x
-- | @since 4.9.0.0
instance Functor First where
fmap f (First x) = First (f x)
-- | @since 4.9.0.0
instance Foldable First where
foldMap f (First a) = f a
-- | @since 4.9.0.0
instance Traversable First where
traverse f (First a) = First `fmap` f a
-- | @since 4.9.0.0
instance Applicative First where
pure x = First x
a <* _ = a
_ *> a = a
(<*>) = coerce
liftA2 = coerce
-- | @since 4.9.0.0
instance Monad First where
(>>) = (*>)
First a >>= f = f a
-- | @since 4.9.0.0
instance MonadFix First where
mfix f = fix (f . getFirst)
-- |
-- Beware that @Data.Semigroup.@'Last' is different from
-- @Data.Monoid.@'Data.Monoid.Last'. The former simply returns the last value,
-- so @x <> Data.Semigroup.Last Nothing = Data.Semigroup.Last Nothing@.
-- The latter returns the last non-'Nothing',
-- thus @x <> Data.Monoid.Last Nothing = x@.
--
-- ==== __Examples__
--
-- >>> Last 0 <> Last 10
-- Last {getLast = 10}
--
-- >>> sconcat $ Last 1 :| [ Last n | n <- [2..]]
-- Last {getLast = * hangs forever *
newtype Last a = Last { getLast :: a }
deriving ( Bounded -- ^ @since 4.9.0.0
, Eq -- ^ @since 4.9.0.0
, Ord -- ^ @since 4.9.0.0
, Show -- ^ @since 4.9.0.0
, Read -- ^ @since 4.9.0.0
, Data -- ^ @since 4.9.0.0
, Generic -- ^ @since 4.9.0.0
, Generic1 -- ^ @since 4.9.0.0
)
-- | @since 4.9.0.0
instance Enum a => Enum (Last a) where
succ (Last a) = Last (succ a)
pred (Last a) = Last (pred a)
toEnum = Last . toEnum
fromEnum = fromEnum . getLast
enumFrom (Last a) = Last `fmap` enumFrom a
enumFromThen (Last a) (Last b) = Last `fmap` enumFromThen a b
enumFromTo (Last a) (Last b) = Last `fmap` enumFromTo a b
enumFromThenTo (Last a) (Last b) (Last c) = Last `fmap` enumFromThenTo a b c
-- | @since 4.9.0.0
instance Semigroup (Last a) where
_ <> b = b
stimes = stimesIdempotent
-- | @since 4.9.0.0
instance Functor Last where
fmap f (Last x) = Last (f x)
a <$ _ = Last a
-- | @since 4.9.0.0
instance Foldable Last where
foldMap f (Last a) = f a
-- | @since 4.9.0.0
instance Traversable Last where
traverse f (Last a) = Last `fmap` f a
-- | @since 4.9.0.0
instance Applicative Last where
pure = Last
a <* _ = a
_ *> a = a
(<*>) = coerce
liftA2 = coerce
-- | @since 4.9.0.0
instance Monad Last where
(>>) = (*>)
Last a >>= f = f a
-- | @since 4.9.0.0
instance MonadFix Last where
mfix f = fix (f . getLast)
-- | Provide a Semigroup for an arbitrary Monoid.
--
-- __NOTE__: This is not needed anymore since 'Semigroup' became a superclass of
-- 'Monoid' in /base-4.11/ and this newtype be deprecated at some point in the future.
newtype WrappedMonoid m = WrapMonoid { unwrapMonoid :: m }
deriving ( Bounded -- ^ @since 4.9.0.0
, Eq -- ^ @since 4.9.0.0
, Ord -- ^ @since 4.9.0.0
, Show -- ^ @since 4.9.0.0
, Read -- ^ @since 4.9.0.0
, Data -- ^ @since 4.9.0.0
, Generic -- ^ @since 4.9.0.0
, Generic1 -- ^ @since 4.9.0.0
)
-- | @since 4.9.0.0
instance Monoid m => Semigroup (WrappedMonoid m) where
(<>) = coerce (mappend :: m -> m -> m)
-- | @since 4.9.0.0
instance Monoid m => Monoid (WrappedMonoid m) where
mempty = WrapMonoid mempty
-- This ensures that we use whatever mconcat is defined for the wrapped
-- Monoid.
mconcat = coerce (mconcat :: [m] -> m)
-- | @since 4.9.0.0
instance Enum a => Enum (WrappedMonoid a) where
succ (WrapMonoid a) = WrapMonoid (succ a)
pred (WrapMonoid a) = WrapMonoid (pred a)
toEnum = WrapMonoid . toEnum
fromEnum = fromEnum . unwrapMonoid
enumFrom (WrapMonoid a) = WrapMonoid `fmap` enumFrom a
enumFromThen (WrapMonoid a) (WrapMonoid b) = WrapMonoid `fmap` enumFromThen a b
enumFromTo (WrapMonoid a) (WrapMonoid b) = WrapMonoid `fmap` enumFromTo a b
enumFromThenTo (WrapMonoid a) (WrapMonoid b) (WrapMonoid c) =
WrapMonoid `fmap` enumFromThenTo a b c
-- | Repeat a value @n@ times.
--
-- > mtimesDefault n a = a <> a <> ... <> a -- using <> (n-1) times
--
-- 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:
--
-- @
-- 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.
--
-- ==== __Examples__
--
-- >>> mtimesDefault 0 "bark"
-- []
--
-- >>> mtimesDefault 3 "meow"
-- "meowmeowmeow"
mtimesDefault :: (Integral b, Monoid a) => b -> a -> a
mtimesDefault n x
| n == 0 = mempty
| otherwise = stimes n x