{-# LANGUAGE CPP, MultiParamTypeClasses, FlexibleInstances, FlexibleContexts #-}
-----------------------------------------------------------------------------

-- |

-- License     :  BSD-style (see the file LICENSE)

-- Maintainer  :  Edward Kmett <ekmett@gmail.com>

-- Stability   :  provisional

-- Portability :  portable

--

-- Operations on affine spaces.

-----------------------------------------------------------------------------

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 { forall r a. Covector r a -> (a -> r) -> r
runCovector :: (a -> r) -> r }

infixr 0 $*

($*) :: Representable f => Covector r (Rep f) -> f r -> r
Covector (Rep f -> r) -> r
f $* :: forall (f :: * -> *) r.
Representable f =>
Covector r (Rep f) -> f r -> r
$* f r
m = (Rep f -> r) -> r
f (forall (f :: * -> *) a. Representable f => f a -> Rep f -> a
Rep.index f r
m)

instance Functor (Covector r) where
  fmap :: forall a b. (a -> b) -> Covector r a -> Covector r b
fmap a -> b
f (Covector (a -> r) -> r
m) = forall r a. ((a -> r) -> r) -> Covector r a
Covector forall a b. (a -> b) -> a -> b
$ \b -> r
k -> (a -> r) -> r
m (b -> r
k forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f)

instance Apply (Covector r) where
  Covector ((a -> b) -> r) -> r
mf <.> :: forall a b. Covector r (a -> b) -> Covector r a -> Covector r b
<.> Covector (a -> r) -> r
ma = forall r a. ((a -> r) -> r) -> Covector r a
Covector forall a b. (a -> b) -> a -> b
$ \b -> r
k -> ((a -> b) -> r) -> r
mf forall a b. (a -> b) -> a -> b
$ \a -> b
f -> (a -> r) -> r
ma (b -> r
k forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f)

instance Applicative (Covector r) where
  pure :: forall a. a -> Covector r a
pure a
a = forall r a. ((a -> r) -> r) -> Covector r a
Covector forall a b. (a -> b) -> a -> b
$ \a -> r
k -> a -> r
k a
a
  Covector ((a -> b) -> r) -> r
mf <*> :: forall a b. Covector r (a -> b) -> Covector r a -> Covector r b
<*> Covector (a -> r) -> r
ma = forall r a. ((a -> r) -> r) -> Covector r a
Covector forall a b. (a -> b) -> a -> b
$ \b -> r
k -> ((a -> b) -> r) -> r
mf forall a b. (a -> b) -> a -> b
$ \a -> b
f -> (a -> r) -> r
ma forall a b. (a -> b) -> a -> b
$ b -> r
k forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f

instance Bind (Covector r) where
  Covector (a -> r) -> r
m >>- :: forall a b. Covector r a -> (a -> Covector r b) -> Covector r b
>>- a -> Covector r b
f = forall r a. ((a -> r) -> r) -> Covector r a
Covector forall a b. (a -> b) -> a -> b
$ \b -> r
k -> (a -> r) -> r
m forall a b. (a -> b) -> a -> b
$ \a
a -> forall r a. Covector r a -> (a -> r) -> r
runCovector (a -> Covector r b
f a
a) b -> r
k

instance Monad (Covector r) where
#if !(MIN_VERSION_base(4,11,0))
  return a = Covector $ \k -> k a
#endif
  Covector (a -> r) -> r
m >>= :: forall a b. Covector r a -> (a -> Covector r b) -> Covector r b
>>= a -> Covector r b
f = forall r a. ((a -> r) -> r) -> Covector r a
Covector forall a b. (a -> b) -> a -> b
$ \b -> r
k -> (a -> r) -> r
m forall a b. (a -> b) -> a -> b
$ \a
a -> forall r a. Covector r a -> (a -> r) -> r
runCovector (a -> Covector r b
f a
a) b -> r
k

instance Num r => Alt (Covector r) where
  Covector (a -> r) -> r
m <!> :: forall a. Covector r a -> Covector r a -> Covector r a
<!> Covector (a -> r) -> r
n = forall r a. ((a -> r) -> r) -> Covector r a
Covector forall a b. (a -> b) -> a -> b
$ \a -> r
k -> (a -> r) -> r
m a -> r
k forall a. Num a => a -> a -> a
+ (a -> r) -> r
n a -> r
k

instance Num r => Plus (Covector r) where
  zero :: forall a. Covector r a
zero = forall r a. ((a -> r) -> r) -> Covector r a
Covector (forall a b. a -> b -> a
const r
0)

instance Num r => Alternative (Covector r) where
  Covector (a -> r) -> r
m <|> :: forall a. Covector r a -> Covector r a -> Covector r a
<|> Covector (a -> r) -> r
n = forall r a. ((a -> r) -> r) -> Covector r a
Covector forall a b. (a -> b) -> a -> b
$ \a -> r
k -> (a -> r) -> r
m a -> r
k forall a. Num a => a -> a -> a
+ (a -> r) -> r
n a -> r
k
  empty :: forall a. Covector r a
empty = forall r a. ((a -> r) -> r) -> Covector r a
Covector (forall a b. a -> b -> a
const r
0)

instance Num r => MonadPlus (Covector r) where
  Covector (a -> r) -> r
m mplus :: forall a. Covector r a -> Covector r a -> Covector r a
`mplus` Covector (a -> r) -> r
n = forall r a. ((a -> r) -> r) -> Covector r a
Covector forall a b. (a -> b) -> a -> b
$ \a -> r
k -> (a -> r) -> r
m a -> r
k forall a. Num a => a -> a -> a
+ (a -> r) -> r
n a -> r
k
  mzero :: forall a. Covector r a
mzero = forall r a. ((a -> r) -> r) -> Covector r a
Covector (forall a b. a -> b -> a
const r
0)

instance Coalgebra r m => Num (Covector r m) where
  Covector (m -> r) -> r
f + :: Covector r m -> Covector r m -> Covector r m
+ Covector (m -> r) -> r
g = forall r a. ((a -> r) -> r) -> Covector r a
Covector forall a b. (a -> b) -> a -> b
$ \m -> r
k -> (m -> r) -> r
f m -> r
k forall a. Num a => a -> a -> a
+ (m -> r) -> r
g m -> r
k
  Covector (m -> r) -> r
f - :: Covector r m -> Covector r m -> Covector r m
- Covector (m -> r) -> r
g = forall r a. ((a -> r) -> r) -> Covector r a
Covector forall a b. (a -> b) -> a -> b
$ \m -> r
k -> (m -> r) -> r
f m -> r
k forall a. Num a => a -> a -> a
- (m -> r) -> r
g m -> r
k
  Covector (m -> r) -> r
f * :: Covector r m -> Covector r m -> Covector r m
* Covector (m -> r) -> r
g = forall r a. ((a -> r) -> r) -> Covector r a
Covector forall a b. (a -> b) -> a -> b
$ \m -> r
k -> (m -> r) -> r
f forall a b. (a -> b) -> a -> b
$ \m
m -> (m -> r) -> r
g forall a b. (a -> b) -> a -> b
$ forall r m. Coalgebra r m => (m -> r) -> m -> m -> r
comult m -> r
k m
m
  negate :: Covector r m -> Covector r m
negate (Covector (m -> r) -> r
f) = forall r a. ((a -> r) -> r) -> Covector r a
Covector forall a b. (a -> b) -> a -> b
$ \m -> r
k -> forall a. Num a => a -> a
negate ((m -> r) -> r
f m -> r
k)
  abs :: Covector r m -> Covector r m
abs Covector r m
_    = forall a. HasCallStack => [Char] -> a
error [Char]
"Covector.abs: undefined"
  signum :: Covector r m -> Covector r m
signum Covector r m
_ = forall a. HasCallStack => [Char] -> a
error [Char]
"Covector.signum: undefined"
  fromInteger :: Integer -> Covector r m
fromInteger Integer
n = forall r a. ((a -> r) -> r) -> Covector r a
Covector forall a b. (a -> b) -> a -> b
$ \ m -> r
k -> forall a. Num a => Integer -> a
fromInteger Integer
n forall a. Num a => a -> a -> a
* forall r m. Coalgebra r m => (m -> r) -> r
counital m -> r
k