{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, FlexibleContexts #-} module Linear.Covector ( Covector(..) , ($*) ) where import Control.Applicative import Control.Monad import Data.Functor.Plus hiding (zero) import qualified Data.Functor.Plus as Plus import Data.Functor.Bind import Data.Functor.Rep as Rep import Linear.Algebra -- | Linear functionals from elements of an (infinite) free module to a scalar newtype Covector r a = Covector { runCovector :: (a -> r) -> r } infixr 0 $* ($*) :: Representable f => Covector r (Rep f) -> f r -> r Covector f $* m = f (Rep.index m) instance Functor (Covector r) where fmap f (Covector m) = Covector $ \k -> m (k . f) instance Apply (Covector r) where Covector mf <.> Covector ma = Covector $ \k -> mf $ \f -> ma (k . f) instance Applicative (Covector r) where pure a = Covector $ \k -> k a Covector mf <*> Covector ma = Covector $ \k -> mf $ \f -> ma $ k . f instance Bind (Covector r) where Covector m >>- f = Covector $ \k -> m $ \a -> runCovector (f a) k instance Monad (Covector r) where return a = Covector $ \k -> k a Covector m >>= f = Covector $ \k -> m $ \a -> runCovector (f a) k instance Num r => Alt (Covector r) where Covector m Covector n = Covector $ \k -> m k + n k instance Num r => Plus (Covector r) where zero = Covector (const 0) instance Num r => Alternative (Covector r) where Covector m <|> Covector n = Covector $ \k -> m k + n k empty = Covector (const 0) instance Num r => MonadPlus (Covector r) where Covector m `mplus` Covector n = Covector $ \k -> m k + n k mzero = Covector (const 0) instance Coalgebra r m => Num (Covector r m) where Covector f + Covector g = Covector $ \k -> f k + g k Covector f - Covector g = Covector $ \k -> f k - g k Covector f * Covector g = Covector $ \k -> f $ \m -> g $ comult k m negate (Covector f) = Covector $ \k -> negate (f k) abs _ = error "Covector.abs: undefined" signum _ = error "Covector.signum: undefined" fromInteger n = Covector $ \ k -> fromInteger n * counital k