{-# LANGUAGE CPP #-}
module Numeric.Limp.Rep.Rep where
import Data.Map (Map)
import qualified Data.Map as M
#if MIN_VERSION_base(4,9,0) && !MIN_VERSION_base(4,11,0)
import Data.Semigroup
#endif
class ( Num (Z c), Ord (Z c), Eq (Z c), Integral (Z c)
, Num (R c), Ord (R c), Eq (R c), RealFrac (R c)) => Rep c where
data Z c
data R c
fromZ :: Z c -> R c
fromZ = fromIntegral
data Assignment z r c
= Assignment (Map z (Z c)) (Map r (R c))
deriving instance (Show (Z c), Show (R c), Show z, Show r) => Show (Assignment z r c)
instance (Ord z, Ord r) => Semigroup (Assignment z r c) where
(<>) = mappend
instance (Ord z, Ord r) => Monoid (Assignment z r c) where
mempty = Assignment M.empty M.empty
mappend (Assignment z1 r1) (Assignment z2 r2)
= Assignment (M.union z1 z2) (M.union r1 r2)
zOf :: (Rep c, Ord z) => Assignment z r c -> z -> Z c
zOf (Assignment zs _) z
= maybe 0 id $ M.lookup z zs
rOf :: (Rep c, Ord r) => Assignment z r c -> r -> R c
rOf (Assignment _ rs) r
= maybe 0 id $ M.lookup r rs
zrOf :: (Rep c, Ord z, Ord r) => Assignment z r c -> Either z r -> R c
zrOf a = either (fromZ . zOf a) (rOf a)
assSize :: Assignment z r c -> Int
assSize (Assignment mz mr)
= M.size mz + M.size mr