module Numeric.Covector
( Covector(..)
, counitM
, unitM
, comultM
, multM
, invM
, coinvM
, antipodeM
, convolveM
) where
import Numeric.Additive.Class
import Numeric.Additive.Group
import Numeric.Algebra.Class
import Numeric.Algebra.Unital
import Numeric.Algebra.Idempotent
import Numeric.Algebra.Involutive
import Numeric.Algebra.Commutative
import Numeric.Algebra.Hopf
import Numeric.Rig.Class
import Numeric.Ring.Class
import Control.Applicative
import Control.Monad
import Data.Functor.Plus hiding (zero)
import qualified Data.Functor.Plus as Plus
import Data.Functor.Bind
import Prelude hiding ((+),(),negate,subtract,replicate,(*))
infixr 0 $*
newtype Covector r a = Covector { ($*) :: (a -> r) -> r }
instance Functor (Covector r) where
fmap f m = Covector $ \k -> m $* k . f
instance Apply (Covector r) where
mf <.> ma = Covector $ \k -> mf $* \f -> ma $* k . f
instance Applicative (Covector r) where
pure a = Covector $ \k -> k a
mf <*> ma = Covector $ \k -> mf $* \f -> ma $* k . f
instance Bind (Covector r) where
m >>- f = Covector $ \k -> m $* \a -> f a $* k
instance Monad (Covector r) where
return a = Covector $ \k -> k a
m >>= f = Covector $ \k -> m $* \a -> f a $* k
instance Additive r => Alt (Covector r) where
Covector m <!> Covector n = Covector $ m + n
instance Monoidal r => Plus (Covector r) where
zero = Covector zero
instance Monoidal r => Alternative (Covector r) where
Covector m <|> Covector n = Covector $ m + n
empty = Covector zero
instance Monoidal r => MonadPlus (Covector r) where
Covector m `mplus` Covector n = Covector $ m + n
mzero = Covector zero
instance Additive r => Additive (Covector r a) where
Covector m + Covector n = Covector $ m + n
sinnum1p n (Covector m) = Covector $ sinnum1p n m
instance Coalgebra r m => Multiplicative (Covector r m) where
Covector f * Covector g = Covector $ \k -> f (\m -> g (comult k m))
instance (Commutative m, Coalgebra r m) => Commutative (Covector r m)
instance Coalgebra r m => Semiring (Covector r m)
instance CounitalCoalgebra r m => Unital (Covector r m) where
one = Covector counit
instance (Rig r, CounitalCoalgebra r m) => Rig (Covector r m)
instance (Ring r, CounitalCoalgebra r m) => Ring (Covector r m)
instance Idempotent r => Idempotent (Covector r a)
instance (Idempotent r, IdempotentCoalgebra r a) => Band (Covector r a)
multM :: Coalgebra r c => c -> c -> Covector r c
multM a b = Covector $ \k -> comult k a b
unitM :: CounitalCoalgebra r c => Covector r c
unitM = Covector counit
comultM :: Algebra r a => a -> Covector r (a,a)
comultM c = Covector $ \k -> mult (curry k) c
counitM :: UnitalAlgebra r a => a -> Covector r ()
counitM a = Covector $ \k -> unit (k ()) a
convolveM :: (Algebra r c, Coalgebra r a) => (c -> Covector r a) -> (c -> Covector r a) -> c -> Covector r a
convolveM f g c = do
(c1,c2) <- comultM c
a1 <- f c1
a2 <- g c2
multM a1 a2
invM :: InvolutiveAlgebra r h => h -> Covector r h
invM = Covector . flip inv
coinvM :: InvolutiveCoalgebra r h => h -> Covector r h
coinvM = Covector . flip coinv
antipodeM :: HopfAlgebra r h => h -> Covector r h
antipodeM = Covector . flip antipode
instance Monoidal s => Monoidal (Covector s a) where
zero = Covector zero
sinnum n (Covector m) = Covector (sinnum n m)
instance Abelian s => Abelian (Covector s a)
instance Group s => Group (Covector s a) where
Covector m Covector n = Covector $ m n
negate (Covector m) = Covector $ negate m
subtract (Covector m) (Covector n) = Covector $ subtract m n
times n (Covector m) = Covector $ times n m
instance Coalgebra r m => LeftModule (Covector r m) (Covector r m) where
(.*) = (*)
instance LeftModule r s => LeftModule r (Covector s m) where
s .* m = Covector $ \k -> s .* (m $* k)
instance Coalgebra r m => RightModule (Covector r m) (Covector r m) where
(*.) = (*)
instance RightModule r s => RightModule r (Covector s m) where
m *. s = Covector $ \k -> (m $* k) *. s