group-theory-0.2.0.0: src/Data/Group/Multiplicative.hs
{-# language FlexibleInstances #-}
{-# language Safe #-}
-- |
-- Module : Data.Group.Multiplicative
-- Copyright : (c) 2020 Emily Pillmore
-- License : BSD-style
--
-- Maintainer : Emily Pillmore <emilypi@cohomolo.gy>,
-- Reed Mullanix <reedmullanix@gmail.com>
-- 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)