algebra-4.3.1: src/Numeric/Algebra/Unital/UnitNormalForm.hs
{-# LANGUAGE DefaultSignatures #-}
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
-- prop> let (u,n) = splitUnit r
-- (u',n') = splitUnit r' in
-- isUnit u && isUnit u' &&
-- u*n = r && u'*n' = r' &&
-- (isAssociate r r' ==> n = n') &&
-- splitUnit (r * r') = (u * u', n * n')
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)
{-# INLINE splitUnit #-}
normalize :: UnitNormalForm r => r -> r
normalize = snd . splitUnit
leadingUnit :: UnitNormalForm r => r -> r
leadingUnit = fst . splitUnit