content: {-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-}
  module Numeric.Quadrance.Class
    ( Quadrance(..)
    ) where
  
  import Data.Int
  import Data.Word
  import Numeric.Additive.Class
  import Numeric.Algebra.Class
  import Numeric.Algebra.Unital
  import Numeric.Rig.Class
  import Numeric.Natural
  import Prelude hiding ((+),(*))
  
  -- a module with a computable squared norm
  class Additive r => Quadrance r m where
    quadrance :: m -> r
  
  instance Quadrance () a where 
    quadrance _ = ()
  
  instance (Additive r, Monoidal r) => Quadrance r () where
    quadrance _ = zero
  
  instance (Quadrance r a, Quadrance r b) => Quadrance r (a,b) where
    quadrance (a,b) = quadrance a + quadrance b
  
  instance (Quadrance r a, Quadrance r b, Quadrance r c) => Quadrance r (a,b,c) where
    quadrance (a,b,c) = quadrance a + quadrance b + quadrance c
  
  instance (Quadrance r a, Quadrance r b, Quadrance r c, Quadrance r d) => Quadrance r (a,b,c,d) where
    quadrance (a,b,c,d) = quadrance a + quadrance b + quadrance c + quadrance d
  
  instance (Quadrance r a, Quadrance r b, Quadrance r c, Quadrance r d, Quadrance r e) => Quadrance r (a,b,c,d,e) where
    quadrance (a,b,c,d,e) = quadrance a + quadrance b + quadrance c + quadrance d + quadrance e
  
  instance Rig r => Quadrance r Bool where
    quadrance False = zero
    quadrance True  = one
  
  sq :: Multiplicative r => r -> r
  sq r = r * r
  
  instance Rig r => Quadrance r Int where
    quadrance = fromNatural . fromIntegral . sq . toInteger
  
  instance Rig r => Quadrance r Word where
    quadrance = fromNatural . fromIntegral . sq . toInteger
  
  instance Rig r => Quadrance r Natural where
    quadrance = fromNatural . fromIntegral . sq . toInteger
  
  instance Rig r => Quadrance r Integer where 
    quadrance = fromNatural . fromInteger . sq
  
  instance Rig r => Quadrance r Int8 where 
    quadrance = fromNatural . fromIntegral . sq . toInteger
  
  instance Rig r => Quadrance r Int16 where 
    quadrance = fromNatural . fromIntegral . sq . toInteger
  
  instance Rig r => Quadrance r Int32 where
    quadrance = fromNatural . fromIntegral . sq . toInteger
  
  instance Rig r => Quadrance r Int64 where
    quadrance = fromNatural . fromIntegral . sq . toInteger
  
  instance Rig r => Quadrance r Word8 where 
    quadrance = fromNatural . fromIntegral . sq . toInteger
  
  instance Rig r => Quadrance r Word16 where 
    quadrance = fromNatural . fromIntegral . sq . toInteger
  
  instance Rig r => Quadrance r Word32 where
    quadrance = fromNatural . fromIntegral . sq . toInteger
  
  instance Rig r => Quadrance r Word64 where
    quadrance = fromNatural . fromIntegral . sq . toInteger
  
  {-
  instance InvolutiveSemiring r => Quadrance r (Complex r) where
    quadrance n = e (adjoint n * n)
  
  instance InvolutiveSemiring r => Quadrance r (Quaternion r) where
    quadrance n = e (adjoint n * n)
  -}
  