{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, RebindableSyntax, DeriveFunctor #-} 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