{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeOperators #-}
module Data.Vector.Generic.Sized
( Vector
, fromVector
, replicate
, singleton
, generate
, generateM
, length
, index
, head
, last
, tail
, init
, take
, drop
, map
, imapM_
, foldl'
, foldl1'
) where
import qualified Data.Vector.Generic as VG
import qualified Data.Vector.Storable as VS
import GHC.TypeLits
import Data.Proxy
import Control.DeepSeq
import Foreign.Storable
import Foreign.Ptr (castPtr)
import Prelude hiding (replicate, head, last,
tail, init, map, length, drop, take)
newtype Vector v (n :: Nat) a = Vector (v a)
deriving (Show, Eq, Ord, Foldable, NFData)
instance (KnownNat n, Storable a)
=> Storable (Vector VS.Vector n a) where
sizeOf _ = sizeOf (undefined :: a) * fromIntegral (natVal (Proxy :: Proxy n))
alignment _ = alignment (undefined :: a)
peek ptr = generateM (Proxy :: Proxy n) (peekElemOff (castPtr ptr))
poke ptr = imapM_ (pokeElemOff (castPtr ptr))
fromVector :: forall a v (n :: Nat). (KnownNat n, VG.Vector v a)
=> v a -> Maybe (Vector v n a)
fromVector v
| n' == fromIntegral (VG.length v) = Just (Vector v)
| otherwise = Nothing
where n' = natVal (Proxy :: Proxy n)
{-# INLINE fromVector #-}
singleton :: forall a v. (VG.Vector v a)
=> a -> Vector v 1 a
singleton a = Vector (VG.singleton a)
{-# INLINE singleton #-}
generate :: forall (n :: Nat) a v. (VG.Vector v a, KnownNat n)
=> Proxy n -> (Int -> a) -> Vector v n a
generate n f = Vector (VG.generate (fromIntegral $ natVal n) f)
{-# INLINE generate #-}
generateM :: forall (n :: Nat) a v m. (VG.Vector v a, KnownNat n, Monad m)
=> Proxy n -> (Int -> m a) -> m (Vector v n a)
generateM n f = Vector <$> VG.generateM (fromIntegral $ natVal n) f
{-# INLINE generateM #-}
withVectorUnsafe :: forall a b v (n :: Nat). (VG.Vector v a, VG.Vector v b)
=> (v a -> v b) -> Vector v n a -> Vector v n b
withVectorUnsafe f (Vector v) = Vector (f v)
{-# INLINE withVectorUnsafe #-}
index :: forall (m :: Nat) a v (n :: Nat). (KnownNat n, KnownNat m, VG.Vector v a)
=> Vector v (m+n) a -> Proxy n -> a
index (Vector v) i = v `VG.unsafeIndex` fromIntegral (natVal i)
{-# INLINE index #-}
take :: forall (m :: Nat) a v (n :: Nat). (KnownNat n, KnownNat m, VG.Vector v a)
=> Proxy n -> Vector v (m+n) a -> Vector v n a
take i (Vector v) = Vector (VG.take (fromIntegral $ natVal i) v)
{-# INLINE take #-}
drop :: forall (m :: Nat) a v (n :: Nat). (KnownNat n, KnownNat m, VG.Vector v a)
=> Proxy n -> Vector v (m+n) a -> Vector v m a
drop i (Vector v) = Vector (VG.drop (fromIntegral $ natVal i) v)
{-# INLINE drop #-}
length :: forall a v (n :: Nat). (VG.Vector v a)
=> Vector v n a -> Int
length (Vector v) = VG.length v
{-# INLINE length #-}
head :: forall a v (n :: Nat). (VG.Vector v a)
=> Vector v (n+1) a -> a
head (Vector v) = VG.head v
{-# INLINE head #-}
last :: forall a v (n :: Nat). (VG.Vector v a)
=> Vector v (n+1) a -> a
last (Vector v) = VG.last v
{-# INLINE last #-}
tail :: forall a v (n :: Nat). (VG.Vector v a)
=> Vector v (n+1) a -> Vector v n a
tail (Vector v) = Vector (VG.tail v)
{-# INLINE tail #-}
init :: forall a v (n :: Nat). (VG.Vector v a)
=> Vector v (n+1) a -> Vector v n a
init (Vector v) = Vector (VG.init v)
{-# INLINE init #-}
replicate :: forall a v (n :: Nat). (VG.Vector v a, KnownNat n)
=> a -> Vector v n a
replicate a = Vector (VG.replicate (fromIntegral $ natVal (Proxy :: Proxy n)) a)
{-# INLINE replicate #-}
map :: forall a b v (n :: Nat). (VG.Vector v a, VG.Vector v b)
=> (a -> b) -> Vector v n a -> Vector v n b
map f = withVectorUnsafe (VG.map f)
{-# INLINE map #-}
imapM_ :: forall a v n b m. (VG.Vector v a, Monad m)
=> (Int -> a -> m b) -> Vector v n a -> m ()
imapM_ f (Vector v) = VG.imapM_ f v
{-# INLINE imapM_ #-}
foldl' :: forall a b v (n :: Nat). VG.Vector v b
=> (a -> b -> a) -> a -> Vector v n b -> a
foldl' f z (Vector v) = VG.foldl' f z v
{-# INLINE foldl' #-}
foldl1' :: forall a v (n :: Nat). (VG.Vector v a)
=> (a -> a -> a) -> Vector v (n+1) a -> a
foldl1' f (Vector v) = VG.foldl1' f v
{-# INLINE foldl1' #-}