ref: cb7ae3b919c7ab22cd6cb6003b6b63a5931a6402
dir: /lib/Data/Monoid/Internal.hs/
module Data.Monoid.Internal(module Data.Monoid.Internal) where
import Prelude() -- do not import Prelude
import Primitives
import Control.Applicative
import Control.Error
import Data.Bool
import Data.Bounded
import Data.Eq
import Data.Function
import Data.Functor
import Data.Int
import Data.Integral
import Data.List_Type
import Data.List.NonEmpty_Type
import Data.Ord
import Data.Maybe_Type
import Data.Num
import Data.Records
import Text.Show
class Semigroup a => Monoid a where
mempty :: a
mappend :: a -> a -> a
mappend = (<>)
mconcat :: [a] -> a
mconcat [] = mempty
mconcat (a:as) = a <> mconcat as
---------------------
instance (Monoid b) => Monoid (a -> b) where
mempty _ = mempty
instance (Semigroup b) => Semigroup (a -> b) where
f <> g = \ x -> f x <> g x
---------------------
newtype Endo a = Endo { appEndo :: a -> a }
instance forall a . Semigroup (Endo a) where
Endo f <> Endo g = Endo (f . g)
instance forall a . Monoid (Endo a) where
mempty = Endo id
---------------------
newtype Dual a = Dual { getDual :: a }
deriving (Bounded, Eq, Ord, Show)
instance forall a . Semigroup a => Semigroup (Dual a) where
Dual a <> Dual b = Dual (b <> a)
instance forall a . Monoid a => Monoid (Dual a) where
mempty = Dual mempty
instance Functor Dual where
fmap f (Dual a) = Dual (f a)
instance Applicative Dual where
pure = Dual
Dual f <*> Dual b = Dual (f b)
---------------------
newtype Max a = Max { getMax :: a }
deriving (Bounded, Eq, Ord, Show)
instance forall a . Ord a => Semigroup (Max a) where
Max a <> Max b = Max (a `max` b)
stimes = stimesIdempotent
instance forall a . (Ord a, Bounded a) => Monoid (Max a) where
mempty = Max minBound
---------------------
newtype Min a = Min { getMin :: a }
deriving (Bounded, Eq, Ord, Show)
instance forall a . Ord a => Semigroup (Min a) where
Min a <> Min b = Min (a `min` b)
stimes = stimesIdempotent
instance forall a . (Ord a, Bounded a) => Monoid (Min a) where
mempty = Min maxBound
---------------------
newtype Sum a = Sum { getSum :: a }
deriving (Bounded, Eq, Ord, Show)
instance forall a . Num a => Semigroup (Sum a) where
Sum a <> Sum b = Sum (a + b)
instance forall a . (Num a) => Monoid (Sum a) where
mempty = Sum 0
---------------------
newtype Product a = Product { getProduct :: a }
deriving (Bounded, Eq, Ord, Show)
instance forall a . Num a => Semigroup (Product a) where
Product a <> Product b = Product (a * b)
instance forall a . (Num a) => Monoid (Product a) where
mempty = Product 1
---------------------
newtype All = All { getAll :: Bool }
deriving (Bounded, Eq, Ord, Show)
instance Semigroup All where
All a <> All b = All (a && b)
instance Monoid All where
mempty = All True
---------------------
newtype Any = Any { getAny :: Bool }
deriving (Bounded, Eq, Ord, Show)
instance Semigroup Any where
Any a <> Any b = Any (a || b)
instance Monoid Any where
mempty = Any False
---------------------
instance Semigroup Ordering where
LT <> _ = LT
EQ <> o = o
GT <> _ = GT
instance Monoid Ordering where
mempty = EQ
----------------------
data Arg a b = Arg a b
deriving(Show)
type ArgMin a b = Min (Arg a b)
type ArgMax a b = Max (Arg a b)
instance Functor (Arg a) where
fmap f (Arg x a) = Arg x (f a)
instance Eq a => Eq (Arg a b) where
Arg a _ == Arg b _ = a == b
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
----------------------
newtype Alt f a = Alt (f a)
-- deriving (Show)
getAlt :: Alt f a -> f a
getAlt (Alt x) = x
{-
deriving ( Generic -- ^ @since base-4.8.0.0
, Generic1 -- ^ @since base-4.8.0.0
, Read -- ^ @since base-4.8.0.0
, Show -- ^ @since base-4.8.0.0
, Eq -- ^ @since base-4.8.0.0
, Ord -- ^ @since base-4.8.0.0
, Num -- ^ @since base-4.8.0.0
, Enum -- ^ @since base-4.8.0.0
, Monad -- ^ @since base-4.8.0.0
, MonadPlus -- ^ @since base-4.8.0.0
, Applicative -- ^ @since base-4.8.0.0
, Alternative -- ^ @since base-4.8.0.0
, Functor -- ^ @since base-4.8.0.0
)
-}
instance Alternative f => Semigroup (Alt f a) where
Alt x <> Alt y = Alt (x <|> y)
stimes = stimesMonoid
instance Alternative f => Monoid (Alt f a) where
mempty = Alt empty
----------------------
-- This really belongs in Data.Semigroup,
-- but some functions have Monoid as in the context.
infixr 6 <>
class Semigroup a where
(<>) :: a -> a -> a
sconcat :: NonEmpty a -> a
stimes :: (Integral b, Ord b) => b -> a -> a
sconcat (a :| as) = go a as
where go b (c:cs) = b <> go c cs
go b [] = b
stimes y0 x0
| y0 <= 0 = error "stimes: positive multiplier expected"
| otherwise = f x0 y0
where
f x y
| y `rem` 2 == 0 = f (x <> x) (y `quot` 2)
| y == 1 = x
| otherwise = g (x <> x) (y `quot` 2) x
g x y z
| y `rem` 2 == 0 = g (x <> x) (y `quot` 2) z
| y == 1 = x <> z
| otherwise = g (x <> x) (y `quot` 2) (x <> z)
stimesIdempotent :: (Integral b, Ord b) => b -> a -> a
stimesIdempotent n x =
if n <= 0 then error "stimesIdempotent: positive multiplier expected"
else x
stimesIdempotentMonoid :: (Ord b, Integral b, Monoid a) => b -> a -> a
stimesIdempotentMonoid n x = case compare n 0 of
LT -> error "stimesIdempotentMonoid: negative multiplier"
EQ -> mempty
GT -> x
stimesMonoid :: (Ord b, Integral b, Monoid a) => b -> a -> a
stimesMonoid n x0 = case compare n 0 of
LT -> error "stimesMonoid: negative multiplier"
EQ -> mempty
GT -> f x0 n
where
f x y
| even y = f (x `mappend` x) (y `quot` 2)
| y == 1 = x
| otherwise = g (x `mappend` x) (y `quot` 2) x
g x y z
| even y = g (x `mappend` x) (y `quot` 2) z
| y == 1 = x `mappend` z
| otherwise = g (x `mappend` x) (y `quot` 2) (x `mappend` z)
---------------------