{-# 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.Algebra 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) sinnum1p n (Opposite a) = Opposite (sinnum1p n a) sumWith1 f = Opposite . sumWith1 (runOpposite . f) instance Monoidal r => Monoidal (Opposite r) where zero = Opposite zero sinnum n (Opposite a) = Opposite (sinnum 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 Group r => Group (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 Division r => Division (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 Rig r => Rig (Opposite r) instance Ring r => Ring (Opposite r)