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