{-# LANGUAGE NoImplicitPrelude #-}
module Algebra.Vector where
import qualified Algebra.Ring as Ring
import qualified Algebra.Additive as Additive
import Algebra.Ring ((*))
import Algebra.Additive ((+))
import Data.List (zipWith, foldl)
import Prelude((.), (==), Bool, Functor, fmap)
import qualified Prelude as P
infixr 7 *>
class C v where
zero :: (Additive.C a) => v a
(<+>) :: (Additive.C a) => v a -> v a -> v a
(*>) :: (Ring.C a) => a -> v a -> v a
infixl 6 <+>
class Eq v where
eq :: P.Eq a => v a -> v a -> Bool
infix 4 `eq`
functorScale :: (Functor v, Ring.C a) => a -> v a -> v a
functorScale = fmap . (*)
instance C [] where
zero = Additive.zero
(<+>) = (Additive.+)
(*>) = functorScale
instance C ((->) b) where
zero = Additive.zero
(<+>) = (Additive.+)
(*>) s f = (s*) . f
instance Eq [] where
eq = (==)
linearComb :: (Ring.C a, C v) => [a] -> [v a] -> v a
linearComb c = foldl (<+>) zero . zipWith (*>) c
propCascade :: (C v, Eq v, Ring.C a, P.Eq a) =>
a -> a -> v a -> Bool
propCascade a b c = (a * b) *> c `eq` a *> (b *> c)
propRightDistributive :: (C v, Eq v, Ring.C a, P.Eq a) =>
a -> v a -> v a -> Bool
propRightDistributive a b c = a *> (b <+> c) `eq` a*>b <+> a*>c
propLeftDistributive :: (C v, Eq v, Ring.C a, P.Eq a) =>
a -> a -> v a -> Bool
propLeftDistributive a b c = (a+b) *> c `eq` a*>c <+> b*>c