module Data.Vec.Base where
import Data.Vec.Nat
import Prelude hiding (map,zipWith,foldl,foldr,reverse,
take,drop,head,tail,sum,last,product,
minimum,maximum,length)
import qualified Prelude as P
import Foreign
import Data.Array.Base as Array
import GHC.ST ( ST(..), runST )
import GHC.Prim
import GHC.Base ( Int(..) )
import GHC.Float ( Float(..), Double(..) )
import GHC.Word ( Word8(..) )
data a :. b = !a :. !b
deriving (Eq,Ord,Read)
infixr :.
instance (Show a, ShowVec v) => Show (a:.v) where
show (a:.v) = "(" ++ show a ++ "):." ++ showVec v
class ShowVec v where
showVec :: v -> String
instance ShowVec () where
showVec = show
instance (Show a, ShowVec v) => ShowVec (a:.v) where
showVec (a:.v) = "(" ++ show a ++ "):." ++ showVec v
type Vec2 a = a :. a :. ()
type Vec3 a = a :. (Vec2 a)
type Vec4 a = a :. (Vec3 a)
type Vec5 a = a :. (Vec4 a)
type Vec6 a = a :. (Vec5 a)
type Vec7 a = a :. (Vec6 a)
type Vec8 a = a :. (Vec7 a)
type Vec9 a = a :. (Vec8 a)
type Vec10 a = a :. (Vec9 a)
type Vec11 a = a :. (Vec10 a)
type Vec12 a = a :. (Vec11 a)
type Vec13 a = a :. (Vec12 a)
type Vec14 a = a :. (Vec13 a)
type Vec15 a = a :. (Vec14 a)
type Vec16 a = a :. (Vec15 a)
type Vec17 a = a :. (Vec16 a)
type Vec18 a = a :. (Vec17 a)
type Vec19 a = a :. (Vec18 a)
class Vec n a v | n a -> v, v -> n a where
mkVec :: n -> a -> v
instance Vec N1 a ( a :. () ) where
mkVec _ a = a :. ()
instance Vec (Succ n) a (a':.v) => Vec (Succ (Succ n)) a (a:.a':.v) where
mkVec _ a = a :. (mkVec undefined a)
vec :: (Vec n a v) => a -> v
vec = mkVec undefined
class VecList a v | v -> a where
fromList :: [a] -> v
getElem :: Int -> v -> a
setElem :: Int -> a -> v -> v
instance VecList a (a:.()) where
fromList (a:_) = a :. ()
fromList [] = error "fromList: list too short"
getElem i (a :. _)
| i == 0 = a
| otherwise = error "getElem: index out of bounds"
setElem i a _
| i == 0 = a :. ()
| otherwise = error "setElem: index out of bounds"
instance VecList a (a':.v) => VecList a (a:.(a':.v)) where
fromList (a:as) = a :. fromList as
fromList [] = error "fromList: list too short"
getElem i (a :. v)
| i == 0 = a
| otherwise = getElem (i1) v
setElem i a' (a :. v)
| i == 0 = a' :. v
| otherwise = a :. (setElem (i1) a' v)
class Access n a v | v -> a where
get :: n -> v -> a
set :: n -> a -> v -> v
instance Access N0 a (a :. v) where
get _ (a :. _) = a
set _ a (_ :. v) = a :. v
instance Access n a v => Access (Succ n) a (a :. v) where
get _ (_ :. v) = get (undefined::n) v
set _ a' (a :. v) = a :. (set (undefined::n) a' v)
class Head v a | v -> a where
head :: v -> a
instance Head (a :. as) a where
head (a :. _) = a
class Tail v v_ | v -> v_ where
tail :: v -> v_
instance Tail (a :. as) as where
tail (_ :. as) = as
class Map a b u v | u -> a, v -> b, b u -> v, a v -> u where
map :: (a -> b) -> u -> v
instance Map a b (a :. ()) (b :. ()) where
map f (x :. ()) = (f x) :. ()
instance Map a b (a':.u) (b':.v) => Map a b (a:.a':.u) (b:.b':.v) where
map f (x:.v) = (f x):.(map f v)
class ZipWith a b c u v w | u->a, v->b, w->c, u v c -> w where
zipWith :: (a -> b -> c) -> u -> v -> w
instance ZipWith a b c (a:.()) (b:.()) (c:.()) where
zipWith f (x:._) (y:._) = f x y :.()
instance ZipWith a b c (a:.()) (b:.b:.bs) (c:.()) where
zipWith f (x:._) (y:._) = f x y :.()
instance ZipWith a b c (a:.a:.as) (b:.()) (c:.()) where
zipWith f (x:._) (y:._) = f x y :.()
instance
ZipWith a b c (a':.u) (b':.v) (c':.w)
=> ZipWith a b c (a:.a':.u) (b:.b':.v) (c:.c':.w)
where
zipWith f (x:.u) (y:.v) = f x y :. zipWith f u v
class Fold v a | v -> a where
fold :: (a -> a -> a) -> v -> a
foldl :: (b -> a -> b) -> b -> v -> b
foldr :: (a -> b -> b) -> b -> v -> b
instance Fold (a:.()) a where
fold _ (a:._) = a
foldl f z (a:._) = seq z $ f z a
foldr f z (a:._) = f a z
instance Fold (a':.u) a => Fold (a:.a':.u) a where
fold f (a:.v) = f a (fold f v)
foldl f z (a:.v) = seq z $ f (foldl f z v) a
foldr f z (a:.v) = f a (foldr f z v)
reverse :: (Reverse' () v v') => v -> v'
reverse v = reverse' () v
class Reverse' p v v' | p v -> v' where
reverse' :: p -> v -> v'
instance Reverse' p () p where
reverse' p () = p
instance Reverse' (a:.p) v v' => Reverse' p (a:.v) v' where
reverse' p (a:.v) = reverse' (a:.p) v
class Append v1 v2 v3 | v1 v2 -> v3, v1 v3 -> v2 where
append :: v1 -> v2 -> v3
instance Append () v v where
append _ = id
instance Append (a:.()) v (a:.v) where
append (a:.()) v = a:.v
instance (Append (a':.v1) v2 v3) => Append (a:.a':.v1) v2 (a:.v3) where
append (a:.u) v = a:.(append u v)
class Take n v v' | n v -> v' where
take :: n -> v -> v'
instance Take N0 v () where
take _ _ = ()
instance Take n v v'
=> Take (Succ n) (a:.v) (a:.v') where
take _ (a:.v) = a:.(take (undefined::n) v)
class Drop n v v' | n v -> v' where
drop :: n -> v -> v'
instance Drop N0 v v where
drop _ = id
instance (Drop n (a:.v) v')
=> Drop (Succ n) (a:.a:.v) v' where
drop _ (_:.v) = drop (undefined::n) v
class Last v a | v -> a where
last :: v -> a
instance Last (a:.()) a where
last (a:._) = a
instance Last (a':.v) a => Last (a:.a':.v) a where
last (_:.v) = last v
class Snoc v a v' | v a -> v', v' -> v a where
snoc :: v -> a -> v'
instance Snoc () a (a:.()) where
snoc _ a = (a:.())
instance Snoc v a (a:.v) => Snoc (a:.v) a (a:.a:.v) where
snoc (b:.v) a = b:.(snoc v a)
class Length v n | v -> n where
length :: v -> Int
instance Length () N0 where
length _ = 0
instance (Length v n) => Length (a:.v) (Succ n) where
length _ = 1+length (undefined::v)
sum :: (Fold v a, Num a) => v -> a
sum x = fold (+) x
product :: (Fold v a, Num a) => v -> a
product x = fold (*) x
maximum :: (Fold v a, Ord a) => v -> a
maximum x = fold max x
minimum :: (Fold v a, Ord a) => v -> a
minimum x = fold min x
toList :: (Fold v a) => v -> [a]
toList = foldr (:) []
type Mat22 a = Vec2 (Vec2 a)
type Mat23 a = Vec2 (Vec3 a)
type Mat24 a = Vec2 (Vec4 a)
type Mat32 a = Vec3 (Vec2 a)
type Mat33 a = Vec3 (Vec3 a)
type Mat34 a = Vec3 (Vec4 a)
type Mat35 a = Vec3 (Vec5 a)
type Mat36 a = Vec3 (Vec6 a)
type Mat42 a = Vec4 (Vec2 a)
type Mat43 a = Vec4 (Vec3 a)
type Mat44 a = Vec4 (Vec4 a)
type Mat45 a = Vec4 (Vec5 a)
type Mat46 a = Vec4 (Vec6 a)
type Mat47 a = Vec4 (Vec7 a)
type Mat48 a = Vec4 (Vec8 a)
matToLists :: (Fold v a, Fold m v) => m -> [[a]]
matToLists = (P.map toList) . toList
matToList :: (Fold v a, Fold m v) => m -> [a]
matToList = concat . matToLists
matFromLists :: (Vec j a v, Vec i v m, VecList a v, VecList v m) => [[a]] -> m
matFromLists = fromList . (P.map fromList)
matFromList :: forall i j v m a. (Vec i v m, Vec j a v, Nat i, VecList a v, VecList v m) => [a] -> m
matFromList = matFromLists . groupsOf (nat(undefined::i))
where groupsOf n xs = let (a,b) = splitAt n xs in a:(groupsOf n b)
instance Storable a => Storable (a:.()) where
sizeOf _ = sizeOf (undefined::a)
alignment _ = alignment (undefined::a)
peek p = peek (castPtr p) >>= \a -> return (a:.())
peekByteOff p o = peek (p`plusPtr`o)
peekElemOff p i = peek (p`plusPtr`(i*sizeOf(undefined::a)))
poke p (a:._) = poke (castPtr p) a
pokeByteOff p o x = poke (p`plusPtr`o) x
pokeElemOff p i x = poke (p`plusPtr`(i*sizeOf(undefined::a))) x
instance (Vec (Succ (Succ n)) a (a:.a:.v), Storable a, Storable (a:.v))
=> Storable (a:.a:.v)
where
sizeOf _ = sizeOf (undefined::a) + sizeOf (undefined::(a:.v))
alignment _ = alignment (undefined::a)
peek p =
peek (castPtr p) >>= \a ->
peek (castPtr (p`plusPtr`sizeOf(undefined::a))) >>= \v ->
return (a:.v)
peekByteOff p o = peek (p`plusPtr`o)
peekElemOff p i = peek (p`plusPtr`(i*sizeOf(undefined::(a:.a:.v))))
poke p (a:.v) =
poke (castPtr p) a >>
poke (castPtr (p`plusPtr`sizeOf(undefined::a))) v
pokeByteOff p o x = poke (p`plusPtr`o) x
pokeElemOff p i x = poke (p`plusPtr`(i*sizeOf(undefined::(a:.a:.v)))) x
instance
(Num a
,Map a a (a:.u) (a:.u)
,ZipWith a a a (a:.u) (a:.u) (a:.u)
,Vec (Succ l) a (a:.u)
)
=> Num (a:.u)
where
(+) u v = zipWith (+) u v
() u v = zipWith () u v
(*) u v = zipWith (*) u v
abs u = map abs u
signum u = map signum u
fromInteger i = vec (fromInteger i)
instance
(Fractional a
,Ord (a:.u)
,ZipWith a a a (a:.u) (a:.u) (a:.u)
,Map a a (a:.u) (a:.u)
,Vec (Succ l) a (a:.u)
)
=> Fractional (a:.u)
where
(/) u v = zipWith (/) u v
recip u = map recip u
fromRational r = vec (fromRational r)
sizeOf# :: Storable a => a -> Int#
sizeOf# x = case sizeOf x of I# n# -> n#
class VecArrayRW v where
vaRead# :: MutableByteArray# s# -> Int# -> State# s# -> (# State# s#, v #)
vaWrite# :: MutableByteArray# s# -> Int# -> v -> State# s# -> State# s#
vaIndex# :: ByteArray# -> Int# -> v
vaSizeOf# :: v -> Int#
vaLength# :: v -> Int#
init# :: v
instance VecArrayRW (Int:.()) where
vaRead# arr# i# s1# =
case readIntArray# arr# i# s1# of
(# s2#, x# #) -> (# s2#, ((I# x#):.()) #)
vaWrite# arr# i# ((I# x#):._) s1# =
case writeIntArray# arr# i# x# s1# of { s2# -> s2# }
vaIndex# arr# i# = I# (indexIntArray# arr# i#) :. ()
vaSizeOf# _ = sizeOf# (undefined::Int)
vaLength# _ = 1#
init# = 0:.()
instance (VecArrayRW (Int:.v)) => VecArrayRW (Int:.Int:.v) where
vaRead# arr# i# s1# =
case readIntArray# arr# i# s1# of { (# s2#, x# #) ->
case vaRead# arr# (i# +# 1#) s2# of { (# s3#, v #) ->
(# s3#, ((I# x#):.v) #) }}
vaWrite# arr# i# ((I# x#):.v) s1# =
case writeIntArray# arr# i# x# s1# of { s2# ->
case vaWrite# arr# (i# +# 1#) v s2# of { s3# -> s3# }}
vaIndex# arr# i# = I# (indexIntArray# arr# i#) :.
vaIndex# arr# (i# +# 1#)
vaSizeOf# _ = sizeOf# (undefined::Int) +# vaSizeOf# (undefined::Int:.v)
vaLength# _ = 1# +# vaLength# (undefined::Int:.v)
init# = 0 :. init#
instance VecArrayRW (Double:.()) where
vaRead# arr# i# s1# =
case readDoubleArray# arr# i# s1# of
(# s2#, x# #) -> (# s2#, ((D# x#):.()) #)
vaWrite# arr# i# ((D# x#):._) s1# =
case writeDoubleArray# arr# i# x# s1# of { s2# -> s2# }
vaIndex# arr# i# = D# (indexDoubleArray# arr# i#) :. ()
vaSizeOf# _ = sizeOf# (undefined::Double)
vaLength# _ = 1#
init# = 0:.()
instance (VecArrayRW (Double:.v)) => VecArrayRW (Double:.Double:.v) where
vaRead# arr# i# s1# =
case readDoubleArray# arr# i# s1# of { (# s2#, x# #) ->
case vaRead# arr# (i# +# 1#) s2# of { (# s3#, v #) ->
(# s3#, ((D# x#):.v) #) }}
vaWrite# arr# i# ((D# x#):.v) s1# =
case writeDoubleArray# arr# i# x# s1# of { s2# ->
case vaWrite# arr# (i# +# 1#) v s2# of { s3# -> s3# }}
vaIndex# arr# i# = D# (indexDoubleArray# arr# i#) :.
vaIndex# arr# (i# +# 1#)
vaSizeOf# _ = sizeOf# (undefined::Double) +# vaSizeOf# (undefined::Double:.v)
vaLength# _ = 1# +# vaLength# (undefined::Double:.v)
init# = 0 :. init#
instance VecArrayRW (Float:.()) where
vaRead# arr# i# s1# =
case readFloatArray# arr# i# s1# of
(# s2#, x# #) -> (# s2#, ((F# x#):.()) #)
vaWrite# arr# i# ((F# x#):._) s1# =
case writeFloatArray# arr# i# x# s1# of { s2# -> s2# }
vaIndex# arr# i# = F# (indexFloatArray# arr# i#) :. ()
vaSizeOf# _ = sizeOf# (undefined::Float)
vaLength# _ = 1#
init# = 0:.()
instance (VecArrayRW (Float:.v)) => VecArrayRW (Float:.Float:.v) where
vaRead# arr# i# s1# =
case readFloatArray# arr# i# s1# of { (# s2#, x# #) ->
case vaRead# arr# (i# +# 1#) s2# of { (# s3#, v #) ->
(# s3#, ((F# x#):.v) #) }}
vaWrite# arr# i# ((F# x#):.v) s1# =
case writeFloatArray# arr# i# x# s1# of { s2# ->
case vaWrite# arr# (i# +# 1#) v s2# of { s3# -> s3# }}
vaIndex# arr# i# = F# (indexFloatArray# arr# i#) :.
vaIndex# arr# (i# +# 1#)
vaSizeOf# _ = sizeOf# (undefined::Float) +# vaSizeOf# (undefined::Float:.v)
vaLength# _ = 1# +# vaLength# (undefined::Float:.v)
init# = 0 :. init#
instance VecArrayRW (Word8:.()) where
vaRead# arr# i# s1# =
case readWord8Array# arr# i# s1# of
(# s2#, x# #) -> (# s2#, ((W8# x#):.()) #)
vaWrite# arr# i# ((W8# x#):._) s1# =
case writeWord8Array# arr# i# x# s1# of { s2# -> s2# }
vaIndex# arr# i# = W8# (indexWord8Array# arr# i#) :. ()
vaSizeOf# _ = sizeOf# (undefined::Word8)
vaLength# _ = 1#
init# = 0:.()
instance (VecArrayRW (Word8:.v)) => VecArrayRW (Word8:.Word8:.v) where
vaRead# arr# i# s1# =
case readWord8Array# arr# i# s1# of { (# s2#, x# #) ->
case vaRead# arr# (i# +# 1#) s2# of { (# s3#, v #) ->
(# s3#, ((W8# x#):.v) #) }}
vaWrite# arr# i# ((W8# x#):.v) s1# =
case writeWord8Array# arr# i# x# s1# of { s2# ->
case vaWrite# arr# (i# +# 1#) v s2# of { s3# -> s3# }}
vaIndex# arr# i# = W8# (indexWord8Array# arr# i#) :.
vaIndex# arr# (i# +# 1#)
vaSizeOf# _ = sizeOf# (undefined::Word8) +# vaSizeOf# (undefined::Word8:.v)
vaLength# _ = 1# +# vaLength# (undefined::Word8:.v)
init# = 0 :. init#
instance VecArrayRW (a:.v) => MArray (STUArray s) (a:.v) (ST s) where
getBounds (STUArray l u _ _) = return (l,u)
getNumElements (STUArray _ _ n _) = return n
unsafeNewArray_ (l,u) =
unsafeNewArraySTUArray_ (l,u) (\x# -> x# *# vaSizeOf# (undefined::a:.v) )
newArray_ arrBounds = Array.newArray arrBounds init#
unsafeRead (STUArray _ _ _ marr#) (I# i#) = ST $ \s1# ->
vaRead# marr# (vaLength# (undefined::a:.v) *# i#) s1#
unsafeWrite (STUArray _ _ _ marr#) (I# i#) v = ST $ \s1# ->
case vaWrite# marr# (vaLength# (undefined::a:.v) *# i#) v s1# of s2# -> (# s2#, () #)
instance VecArrayRW (a:.v) => IArray UArray (a:.v) where
bounds (UArray l u _ _) = (l,u)
numElements (UArray _ _ n _) = n
unsafeArray lu ies = runST (unsafeArrayUArray lu ies init# )
unsafeAt (UArray _ _ _ arr#) (I# i#) =
vaIndex# arr# (vaLength# (undefined::a:.v) *# i#)
unsafeReplace arr ies = runST (unsafeReplaceUArray arr ies)
unsafeAccum f arr ies = runST (unsafeAccumUArray f arr ies)
unsafeAccumArray f initialValue lu ies =
runST (unsafeAccumArrayUArray f initialValue lu ies)