{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-} module Numeric.Ring.Opposite ( Opposite(..) ) where import Data.Foldable import Data.Function (on) import Data.Semigroup.Foldable import Data.Semigroup.Traversable import Data.Traversable import Numeric.Addition import Numeric.Multiplication import Numeric.Module import Numeric.Band.Class import Numeric.Semiring.Class import Numeric.Rig.Class import Numeric.Rng.Class import Numeric.Ring.Class import Numeric.Decidable.Associates import Numeric.Decidable.Units import Numeric.Decidable.Zero import Prelude hiding ((-),(+),(*),(/),(^),recip,negate,subtract,replicate) -- | http://en.wikipedia.org/wiki/Opposite_ring newtype Opposite r = Opposite { runOpposite :: r } deriving (Show,Read) instance Eq r => Eq (Opposite r) where (==) = (==) `on` runOpposite instance Ord r => Ord (Opposite r) where compare = compare `on` runOpposite instance Functor Opposite where fmap f (Opposite r) = Opposite (f r) instance Foldable Opposite where foldMap f (Opposite r) = f r instance Traversable Opposite where traverse f (Opposite r) = fmap Opposite (f r) instance Foldable1 Opposite where foldMap1 f (Opposite r) = f r instance Traversable1 Opposite where traverse1 f (Opposite r) = fmap Opposite (f r) instance Additive r => Additive (Opposite r) where Opposite a + Opposite b = Opposite (a + b) replicate1p n (Opposite a) = Opposite (replicate1p n a) sumWith1 f = Opposite . sumWith1 (runOpposite . f) instance AdditiveMonoid r => AdditiveMonoid (Opposite r) where zero = Opposite zero replicate n (Opposite a) = Opposite (replicate n a) sumWith f = Opposite . sumWith (runOpposite . f) instance Semiring r => LeftModule (Opposite r) (Opposite r) where (.*) = (*) instance RightModule r s => LeftModule r (Opposite s) where r .* Opposite s = Opposite (s *. r) instance LeftModule r s => RightModule r (Opposite s) where Opposite s *. r = Opposite (r .* s) instance Semiring r => RightModule (Opposite r) (Opposite r) where (*.) = (*) instance AdditiveGroup r => AdditiveGroup (Opposite r) where negate = Opposite . negate . runOpposite Opposite a - Opposite b = Opposite (a - b) subtract (Opposite a) (Opposite b) = Opposite (subtract a b) times n (Opposite a) = Opposite (times n a) instance Abelian r => Abelian (Opposite r) instance DecidableZero r => DecidableZero (Opposite r) where isZero = isZero . runOpposite instance DecidableUnits r => DecidableUnits (Opposite r) where recipUnit = fmap Opposite . recipUnit . runOpposite instance DecidableAssociates r => DecidableAssociates (Opposite r) where isAssociate (Opposite a) (Opposite b) = isAssociate a b instance Multiplicative r => Multiplicative (Opposite r) where Opposite a * Opposite b = Opposite (b * a) pow1p (Opposite a) n = Opposite (pow1p a n) instance Commutative r => Commutative (Opposite r) instance Idempotent r => Idempotent (Opposite r) instance Band r => Band (Opposite r) instance Unital r => Unital (Opposite r) where one = Opposite one pow (Opposite a) n = Opposite (pow a n) instance MultiplicativeGroup r => MultiplicativeGroup (Opposite r) where recip = Opposite . recip . runOpposite Opposite a / Opposite b = Opposite (b \\ a) Opposite a \\ Opposite b = Opposite (b / a) Opposite a ^ n = Opposite (a ^ n) instance Semiring r => Semiring (Opposite r) instance Rng r => Rng (Opposite r) instance Rig r => Rig (Opposite r) instance Ring r => Ring (Opposite r)