module Algebra.Linear where
import Algebra.Classes
import Data.Map (Map)
import qualified Data.Map.Strict as M
import Prelude hiding (Num(..),(/))
data LinFunc v c = Func (Map v c) c
deriving (Functor,Show)
type Constraint v c = LinFunc v c
instance (Additive c,Ord v) => Additive (LinFunc v c) where
zero = Func zero zero
Func f1 k1 + Func f2 k2 = Func (f1 + f2) (k1 + k2)
instance (Ord v, Group c) => Group (LinFunc v c) where
negate = fmap negate
instance (Ord v,AbelianAdditive c) => AbelianAdditive (LinFunc v c) where
instance (Ord v,Ring c) => Module c (LinFunc v c) where
s *^ Func f k = Func (s *^ f) (s * k)
clean :: (Eq v, Eq c, Ring c) => LinFunc v c -> LinFunc v c
clean (Func f k) = Func (M.fromAscList $ filter ((/=0) . snd) $ M.assocs f) k
var :: Ring c => v -> LinFunc v c
var v = Func (M.singleton v 1) 0