numhask-0.0.1: src/NumHask/Algebra/Multiplicative.hs
{-# LANGUAGE ExtendedDefaultRules #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -Wall #-}
-- | Multiplicate structure
-- Many treatments of a numeric tower treat multiplication differently to addition. NumHask treats these two as exactly symmetrical, and thus departs from the usual mathematical terminology.
module NumHask.Algebra.Multiplicative (
-- ** Multiplicative Structure
MultiplicativeMagma(..)
, MultiplicativeUnital(..)
, MultiplicativeAssociative
, MultiplicativeCommutative
, MultiplicativeInvertible(..)
, MultiplicativeHomomorphic(..)
, MultiplicativeMonoidal
, Multiplicative(..)
, MultiplicativeRightCancellative(..)
, MultiplicativeLeftCancellative(..)
, MultiplicativeGroup(..)
) where
import qualified Protolude as P
import Protolude (Double, Float, Int, Integer, Bool(..))
import Data.Functor.Rep
-- * Multiplicative structure
-- | 'times' is used for the multiplicative magma to distinguish from '*' which, by convention, implies commutativity
class MultiplicativeMagma a where times :: a -> a -> a
instance MultiplicativeMagma Double where times = (P.*)
instance MultiplicativeMagma Float where times = (P.*)
instance MultiplicativeMagma Int where times = (P.*)
instance MultiplicativeMagma Integer where times = (P.*)
instance MultiplicativeMagma Bool where times = (P.&&)
instance (Representable r, MultiplicativeMagma a) => MultiplicativeMagma (r a) where
times = liftR2 times
-- | MultiplicativeUnital
--
-- > one `times` a == a
-- > a `times` one == a
class MultiplicativeMagma a => MultiplicativeUnital a where one :: a
instance MultiplicativeUnital Double where one = 1
instance MultiplicativeUnital Float where one = 1
instance MultiplicativeUnital Int where one = 1
instance MultiplicativeUnital Integer where one = 1
instance MultiplicativeUnital Bool where one = True
instance (Representable r, MultiplicativeUnital a) =>
MultiplicativeUnital (r a) where
one = pureRep one
-- | MultiplicativeCommutative
--
-- > a `times` b == b `times` a
class MultiplicativeMagma a => MultiplicativeCommutative a
instance MultiplicativeCommutative Double
instance MultiplicativeCommutative Float
instance MultiplicativeCommutative Int
instance MultiplicativeCommutative Integer
instance MultiplicativeCommutative Bool
instance (Representable r, MultiplicativeCommutative a) =>
MultiplicativeCommutative (r a)
-- | MultiplicativeAssociative
--
-- > (a `times` b) `times` c == a `times` (b `times` c)
class MultiplicativeMagma a => MultiplicativeAssociative a
instance MultiplicativeAssociative Double
instance MultiplicativeAssociative Float
instance MultiplicativeAssociative Int
instance MultiplicativeAssociative Integer
instance MultiplicativeAssociative Bool
instance (Representable r, MultiplicativeAssociative a) =>
MultiplicativeAssociative (r a)
-- | MultiplicativeInvertible
--
-- > ∀ a ∈ A: recip a ∈ A
--
-- law is true by construction in Haskell
class MultiplicativeMagma a => MultiplicativeInvertible a where recip :: a -> a
instance MultiplicativeInvertible Double where recip = P.recip
instance MultiplicativeInvertible Float where recip = P.recip
instance (Representable r, MultiplicativeInvertible a) =>
MultiplicativeInvertible (r a) where
recip = fmapRep recip
-- | MultiplicativeHomomorphic
--
-- > ∀ a ∈ A: timeshom a ∈ B
--
-- law is true by construction in Haskell
class ( MultiplicativeMagma b) =>
MultiplicativeHomomorphic a b where
timeshom :: a -> b
instance (Representable r, MultiplicativeMagma a) =>
MultiplicativeHomomorphic a (r a) where
timeshom a = pureRep a
instance MultiplicativeMagma a => MultiplicativeHomomorphic a a where
timeshom a = a
-- | MultiplicativeMonoidal
class ( MultiplicativeUnital a
, MultiplicativeAssociative a) =>
MultiplicativeMonoidal a
instance MultiplicativeMonoidal Double
instance MultiplicativeMonoidal Float
instance MultiplicativeMonoidal Int
instance MultiplicativeMonoidal Integer
instance MultiplicativeMonoidal Bool
instance (Representable r, MultiplicativeMonoidal a) =>
MultiplicativeMonoidal (r a)
-- | Multiplicative is commutative, associative and unital under multiplication
--
-- > a * b = b * a
--
-- > (a * b) * c = a * (b * c)
--
-- > one * a = a
--
-- > a * one = a
--
class ( MultiplicativeCommutative a
, MultiplicativeUnital a
, MultiplicativeAssociative a) =>
Multiplicative a where
infixl 7 *
(*) :: a -> a -> a
a * b = times a b
instance Multiplicative Double
instance Multiplicative Float
instance Multiplicative Int
instance Multiplicative Integer
instance Multiplicative Bool
instance (Representable r, Multiplicative a) => Multiplicative (r a)
-- | Non-commutative left divide
class ( MultiplicativeUnital a
, MultiplicativeAssociative a
, MultiplicativeInvertible a) =>
MultiplicativeLeftCancellative a where
infixl 7 ~/
(~/) :: a -> a -> a
a ~/ b = recip b `times` a
-- | Non-commutative right divide
class ( MultiplicativeUnital a
, MultiplicativeAssociative a
, MultiplicativeInvertible a) =>
MultiplicativeRightCancellative a where
infixl 7 /~
(/~) :: a -> a -> a
a /~ b = a `times` recip b
-- | MultiplicativeGroup
--
-- > a / a = one
--
-- > recip a = one / a
--
-- > recip a * a = one
--
class ( Multiplicative a
, MultiplicativeInvertible a) =>
MultiplicativeGroup a where
infixl 7 /
(/) :: a -> a -> a
(/) a b = a `times` recip b
instance MultiplicativeGroup Double
instance MultiplicativeGroup Float
instance (Representable r, MultiplicativeGroup a) => MultiplicativeGroup (r a)