module Numeric.Algebra.Unital.UnitNormalForm
(UnitNormalForm(..), normalize, leadingUnit) where
import Numeric.Algebra.Class
import Numeric.Algebra.Division
import Numeric.Algebra.Unital
import Numeric.Decidable.Units
import Numeric.Decidable.Associates
import Numeric.Decidable.Zero
import Numeric.Semiring.ZeroProduct
import Prelude(Integer,signum,abs,fst,snd,(.), otherwise)
class (DecidableUnits r, DecidableAssociates r) => UnitNormalForm r where
splitUnit :: r -> (r,r)
default splitUnit :: (Division r, ZeroProductSemiring r, DecidableZero r) => r -> (r,r)
splitUnit x | isZero x = (one,zero)
| otherwise = (x,one)
instance UnitNormalForm Integer where
splitUnit 0 = (1, 0)
splitUnit n = (signum n, abs n)
normalize :: UnitNormalForm r => r -> r
normalize = snd . splitUnit
leadingUnit :: UnitNormalForm r => r -> r
leadingUnit = fst . splitUnit