module Data.VectorSpace.Free ( module Linear.V0
, module Linear.V1
, module Linear.V2
, module Linear.V3
, module Linear.V4
, AffineSpace(..), AdditiveGroup(..)
, VectorSpace(..), InnerSpace(..)
) where
import Data.AffineSpace
import Data.VectorSpace
import Data.Basis
import Data.MemoTrie
import qualified Linear as L
import Linear.V0
import Linear.V1
import Linear.V2
import Linear.V3
import Linear.V4
import qualified Linear.Affine as LA
import Control.Lens
vDecomp :: FoldableWithIndex (L.E v) v => v s -> [(L.E v, s)]
vDecomp = ifoldr (\b s l -> (b,s):l) []
#define portFinDV(v) \
instance Num s => AffineSpace (v s) where { \
type Diff (v s) = v s; \
(.-.) = (L.^-^); \
(.+^) = (L.^+^) }; \
instance Num s => AdditiveGroup (v s) where { \
zeroV = L.zero; \
(^+^) = (L.^+^); \
negateV = L.negated }; \
instance Num s => VectorSpace (v s) where { \
type Scalar (v s) = s; \
(*^) = (L.*^) }; \
instance (Num s, AdditiveGroup s) => InnerSpace (v s) where { \
(<.>) = L.dot }; \
instance (Num s, AdditiveGroup s) => HasBasis (v s) where { \
type Basis (v s) = L.E v; \
decompose = vDecomp; \
basisValue = L.unit . L.el; \
decompose' w (L.E le) = w^.le }
portFinDV(V0)
portFinDV(V1)
portFinDV(V2)
portFinDV(V3)
portFinDV(V4)
#define portFinDP(v) \
instance Num s => AffineSpace (LA.Point v s) where { \
type Diff (LA.Point v s) = v s; \
(.-.) = (LA..-.); \
(.+^) = (LA..+^) }
portFinDP(V0)
portFinDP(V1)
portFinDP(V2)
portFinDP(V3)
portFinDP(V4)
instance HasTrie (L.E V0) where
newtype L.E V0 :->: a = V0T (V0 a)
trie f = V0T V0
untrie (V0T v) (L.E i) = v^.i
enumerate (V0T V0) = []
instance HasTrie (L.E V1) where
newtype L.E V1 :->: a = V1T (V1 a)
trie f = V1T $ V1 (f L.ex)
untrie (V1T v) (L.E i) = v^.i
enumerate (V1T (V1 x)) = [(L.ex, x)]
instance HasTrie (L.E V2) where
newtype L.E V2 :->: a = V2T (V2 a)
trie f = V2T $ V2 (f L.ex) (f L.ey)
untrie (V2T v) (L.E i) = v^.i
enumerate (V2T (V2 x y)) = [(L.ex, x), (L.ey, y)]
instance HasTrie (L.E V3) where
newtype L.E V3 :->: a = V3T (V3 a)
trie f = V3T $ V3 (f L.ex) (f L.ey) (f L.ez)
untrie (V3T v) (L.E i) = v^.i
enumerate (V3T (V3 x y z)) = [(L.ex, x), (L.ey, y), (L.ez, z)]
instance HasTrie (L.E V4) where
newtype L.E V4 :->: a = V4T (V4 a)
trie f = V4T $ V4 (f L.ex) (f L.ey) (f L.ez) (f L.ew)
untrie (V4T v) (L.E i) = v^.i
enumerate (V4T (V4 x y z w)) = [(L.ex, x), (L.ey, y), (L.ez, z), (L.ew, w)]