{-# language FlexibleInstances #-} {-# language Safe #-} -- | -- Module : Data.Group.Multiplicative -- Copyright : (c) 2020-2021 Emily Pillmore -- License : BSD-style -- -- Maintainer : Emily Pillmore , -- Reed Mullanix -- Stability : stable -- Portability : non-portable -- -- This module contains definitions for 'MultiplicativeGroup' and -- 'MultiplicativeAbelianGroup', along with the relevant combinators. -- module Data.Group.Multiplicative ( -- * Multiplicative Groups MultiplicativeGroup -- ** combinators , (/) , (*) , (^) , power -- * Multiplicative abelian groups , MultiplicativeAbelianGroup ) where import Data.Functor.Const import Data.Functor.Identity import Data.Group import Data.Proxy import Data.Semigroup import Prelude hiding ((^), (/), (*)) infixl 7 /, * infixr 8 ^ -- $setup -- -- >>> import qualified Prelude -- >>> import Data.Group -- >>> import Data.Monoid -- >>> import Data.Semigroup -- >>> :set -XTypeApplications -- -------------------------------------------------------------------- -- -- Multiplicative groups -- | An multiplicative group is a 'Group' whose operation can be thought of -- as multiplication in some sense. -- -- For example, the multiplicative group of rationals \( (ℚ, 1, *) \). -- class Group g => MultiplicativeGroup g instance MultiplicativeGroup () instance MultiplicativeGroup b => MultiplicativeGroup (a -> b) instance MultiplicativeGroup a => MultiplicativeGroup (Dual a) instance Fractional a => MultiplicativeGroup (Product a) instance (MultiplicativeGroup a, MultiplicativeGroup b) => MultiplicativeGroup (a,b) instance (MultiplicativeGroup a, MultiplicativeGroup b, MultiplicativeGroup c) => MultiplicativeGroup (a,b,c) instance (MultiplicativeGroup a, MultiplicativeGroup b, MultiplicativeGroup c, MultiplicativeGroup d) => MultiplicativeGroup (a,b,c,d) instance (MultiplicativeGroup a, MultiplicativeGroup b, MultiplicativeGroup c, MultiplicativeGroup d, MultiplicativeGroup e) => MultiplicativeGroup (a,b,c,d,e) instance MultiplicativeGroup a => MultiplicativeGroup (Const a b) instance MultiplicativeGroup a => MultiplicativeGroup (Identity a) instance MultiplicativeGroup a => MultiplicativeGroup (Proxy a) -- | Infix alias for multiplicative inverse. -- -- === __Examples__: -- -- >>> let x = Product (4 :: Rational) -- >>> x / 2 -- Product {getProduct = 2 % 1} -- (/) :: MultiplicativeGroup a => a -> a -> a (/) = minus {-# inline (/) #-} -- | Infix alias for multiplicative @('<>')@. -- -- === __Examples__: -- -- >>> Product (2 :: Rational) * Product (3 :: Rational) -- Product {getProduct = 6 % 1} -- (*) :: MultiplicativeGroup g => g -> g -> g (*) = (<>) {-# inline (*) #-} -- | Infix alias for 'power'. -- -- === __Examples__: -- -- >>> let x = Product (3 :: Rational) -- >>> x ^ 3 -- Product {getProduct = 27 % 1} -- (^) :: (Integral n, MultiplicativeGroup a) => a -> n -> a (^) = power {-# inline (^) #-} -- | Multiply an element of a multiplicative group by itself @n@-many times. -- -- This represents @ℕ@-indexed powers of an element @g@ of -- a multiplicative group, i.e. iterated products of group elements. -- This is representable by the universal property -- \( C(x, ∏_n g) ≅ C(x, g)^n \). -- -- === __Examples__: -- -- >>> power (Product (3 :: Rational)) 3 -- Product {getProduct = 27 % 1} -- power :: (Integral n, MultiplicativeGroup g) => g -> n -> g power a n = gtimes n a {-# inline power #-} -- -------------------------------------------------------------------- -- -- Multiplicative abelian groups -- | A multiplicative abelian group is a 'Group' whose operation can be thought of -- as commutative multiplication in some sense. Almost all multiplicative groups -- are abelian. -- class (MultiplicativeGroup g, Abelian g) => MultiplicativeAbelianGroup g instance MultiplicativeAbelianGroup () instance MultiplicativeAbelianGroup b => MultiplicativeAbelianGroup (a -> b) instance MultiplicativeAbelianGroup a => MultiplicativeAbelianGroup (Dual a) instance Fractional a => MultiplicativeAbelianGroup (Product a) instance (MultiplicativeAbelianGroup a, MultiplicativeAbelianGroup b) => MultiplicativeAbelianGroup (a,b) instance (MultiplicativeAbelianGroup a, MultiplicativeAbelianGroup b, MultiplicativeAbelianGroup c) => MultiplicativeAbelianGroup (a,b,c) instance (MultiplicativeAbelianGroup a, MultiplicativeAbelianGroup b, MultiplicativeAbelianGroup c, MultiplicativeAbelianGroup d) => MultiplicativeAbelianGroup (a,b,c,d) instance (MultiplicativeAbelianGroup a, MultiplicativeAbelianGroup b, MultiplicativeAbelianGroup c, MultiplicativeAbelianGroup d, MultiplicativeAbelianGroup e) => MultiplicativeAbelianGroup (a,b,c,d,e) instance MultiplicativeAbelianGroup a => MultiplicativeAbelianGroup (Const a b) instance MultiplicativeAbelianGroup a => MultiplicativeAbelianGroup (Identity a) instance MultiplicativeAbelianGroup a => MultiplicativeAbelianGroup (Proxy a)