{-# LANGUAGE NoImplicitPrelude #-}
module Number.Physical.Unit where
import MathObj.DiscreteMap (strip)
import qualified Data.Map as Map
import Data.Map (Map)
import Data.Maybe(fromJust,fromMaybe)
import qualified Number.Ratio as Ratio
import Data.Maybe.HT(toMaybe)
import NumericPrelude.Base
import NumericPrelude.Numeric
type T i = Map i Int
scalar :: T i
scalar = Map.empty
isScalar :: T i -> Bool
isScalar = Map.null
fromVector :: (Enum i, Ord i) => [Int] -> T i
fromVector x = strip (Map.fromList (zip [toEnum 0 .. toEnum ((length x)-1)] x))
toVector :: (Enum i, Ord i) => T i -> [Int]
toVector x = map (flip (Map.findWithDefault 0) x)
[(toEnum 0)..(maximum (Map.keys x))]
ratScale :: Ratio.T Int -> T i -> T i
ratScale expo =
fmap (fromMaybe (error "Physics.Quantity.Unit.ratScale: fractional result")) .
ratScaleMaybe2 expo
ratScaleMaybe :: Ratio.T Int -> T i -> Maybe (T i)
ratScaleMaybe expo u =
let fmMaybe = ratScaleMaybe2 expo u
in toMaybe (not (Nothing `elem` Map.elems fmMaybe))
(fmap fromJust fmMaybe)
ratScaleMaybe2 :: Ratio.T Int -> T i -> Map i (Maybe Int)
ratScaleMaybe2 expo =
fmap (\c -> let y = Ratio.scale c expo
in toMaybe (denominator y == 1) (numerator y))