content: {-# 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)
  