{-# LANGUAGE CPP #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE RankNTypes #-}
module Data.Vector.Generic.Mutable.Sized
( MVector
, length
, length'
, null
, slice
, slice'
, init
, tail
, take
, take'
, drop
, drop'
, splitAt
, splitAt'
, overlaps
, new
, unsafeNew
, replicate
, replicate'
, replicateM
, replicateM'
, clone
, grow
, growFront
, clear
, read
, read'
, write
, write'
, modify
, modify'
, swap
, exchange
, exchange'
, unsafeRead
, unsafeWrite
, unsafeModify
, unsafeSwap
, unsafeExchange
#if MIN_VERSION_vector(0,12,0)
, nextPermutation
#endif
, set
, copy
, move
, unsafeCopy
, toSized
, withSized
, fromSized
) where
import qualified Data.Vector.Generic.Mutable as VGM
import Data.Vector.Generic.Mutable.Sized.Internal
import GHC.TypeLits
import Data.Finite
import Data.Proxy
import Control.Monad.Primitive
import Prelude hiding ( length, null, replicate, init,
tail, take, drop, splitAt, read )
length :: forall v n s a. (KnownNat n)
=> MVector v n s a -> Int
length _ = fromInteger (natVal (Proxy :: Proxy n))
{-# inline length #-}
length' :: forall v n s a. (KnownNat n)
=> MVector v n s a -> Proxy n
length' _ = Proxy
{-# inline length' #-}
null :: forall v n s a. (KnownNat n)
=> MVector v n s a -> Bool
null = (== 0) . length
{-# inline null #-}
slice :: forall v i n k s a p. (KnownNat i, KnownNat n, KnownNat k, VGM.MVector v a)
=> p i
-> MVector v (i+n+k) s a
-> MVector v n s a
slice start (MVector v) = MVector (VGM.unsafeSlice i n v)
where i = fromInteger (natVal start)
n = fromInteger (natVal (Proxy :: Proxy n))
{-# inline slice #-}
slice' :: forall v i n k s a p
. (KnownNat i, KnownNat n, KnownNat k, VGM.MVector v a)
=> p i
-> p n
-> MVector v (i+n+k) s a
-> MVector v n s a
slice' start _ = slice start
{-# inline slice' #-}
init :: forall v n s a. (VGM.MVector v a)
=> MVector v (n+1) s a -> MVector v n s a
init (MVector v) = MVector (VGM.unsafeInit v)
{-# inline init #-}
tail :: forall v n s a. (VGM.MVector v a)
=> MVector v (1+n) s a -> MVector v n s a
tail (MVector v) = MVector (VGM.unsafeTail v)
{-# inline tail #-}
take :: forall v n k s a. (KnownNat n, KnownNat k, VGM.MVector v a)
=> MVector v (n+k) s a -> MVector v n s a
take (MVector v) = MVector (VGM.unsafeTake i v)
where i = fromInteger (natVal (Proxy :: Proxy n))
{-# inline take #-}
take' :: forall v n k s a p. (KnownNat n, KnownNat k, VGM.MVector v a)
=> p n -> MVector v (n+k) s a -> MVector v n s a
take' _ = take
{-# inline take' #-}
drop :: forall v n k s a. (KnownNat n, KnownNat k, VGM.MVector v a)
=> MVector v (n+k) s a -> MVector v k s a
drop (MVector v) = MVector (VGM.unsafeDrop i v)
where i = fromInteger (natVal (Proxy :: Proxy n))
{-# inline drop #-}
drop' :: forall v n k s a p. (KnownNat n, KnownNat k, VGM.MVector v a)
=> p n -> MVector v (n+k) s a -> MVector v k s a
drop' _ = drop
{-# inline drop' #-}
splitAt :: forall v n m s a. (KnownNat n, KnownNat m, VGM.MVector v a)
=> MVector v (n+m) s a -> (MVector v n s a, MVector v m s a)
splitAt (MVector v) = (MVector a, MVector b)
where i = fromInteger (natVal (Proxy :: Proxy n))
(a, b) = VGM.splitAt i v
{-# inline splitAt #-}
splitAt' :: forall v n m s a p. (KnownNat n, KnownNat m, VGM.MVector v a)
=> p n -> MVector v (n+m) s a -> (MVector v n s a, MVector v m s a)
splitAt' _ = splitAt
{-# inline splitAt' #-}
overlaps :: forall v n k s a. (KnownNat n, KnownNat k, VGM.MVector v a)
=> MVector v n s a
-> MVector v k s a
-> Bool
overlaps (MVector v) (MVector u) = VGM.overlaps v u
{-# inline overlaps #-}
new :: forall v n m a. (KnownNat n, PrimMonad m, VGM.MVector v a)
=> m (MVector v n (PrimState m) a)
new = MVector <$> VGM.new (fromIntegral (natVal (Proxy :: Proxy n)))
{-# inline new #-}
unsafeNew :: forall v n m a. (KnownNat n, PrimMonad m, VGM.MVector v a)
=> m (MVector v n (PrimState m) a)
unsafeNew = MVector <$> VGM.new (fromIntegral (natVal (Proxy :: Proxy n)))
{-# inline unsafeNew #-}
replicate :: forall v n m a. (KnownNat n, PrimMonad m, VGM.MVector v a)
=> a -> m (MVector v n (PrimState m) a)
replicate = fmap MVector . VGM.replicate (fromIntegral (natVal (Proxy :: Proxy n)))
{-# inline replicate #-}
replicate' :: forall v n m a p. (KnownNat n, PrimMonad m, VGM.MVector v a)
=> p n -> a -> m (MVector v n (PrimState m) a)
replicate' _ = replicate
{-# inline replicate' #-}
replicateM :: forall v n m a. (KnownNat n, PrimMonad m, VGM.MVector v a)
=> m a -> m (MVector v n (PrimState m) a)
replicateM = fmap MVector . VGM.replicateM (fromIntegral (natVal (Proxy :: Proxy n)))
{-# inline replicateM #-}
replicateM' :: forall v n m a p. (KnownNat n, PrimMonad m, VGM.MVector v a)
=> p n -> m a -> m (MVector v n (PrimState m) a)
replicateM' _ = replicateM
{-# inline replicateM' #-}
clone :: forall v n m a. (PrimMonad m, VGM.MVector v a)
=> MVector v n (PrimState m) a -> m (MVector v n (PrimState m) a)
clone (MVector v) = MVector <$> VGM.clone v
{-# inline clone #-}
grow :: forall v n k m a p. (KnownNat k, PrimMonad m, VGM.MVector v a)
=> p k -> MVector v n (PrimState m) a -> m (MVector v (n + k) (PrimState m) a)
grow _ (MVector v) = MVector <$> VGM.unsafeGrow v (fromIntegral (natVal (Proxy :: Proxy k)))
{-# inline grow #-}
growFront :: forall v n k m a p. (KnownNat k, PrimMonad m, VGM.MVector v a)
=> p k -> MVector v n (PrimState m) a -> m (MVector v (n + k) (PrimState m) a)
growFront _ (MVector v) = MVector <$>
VGM.unsafeGrowFront v (fromIntegral (natVal (Proxy :: Proxy k)))
{-# inline growFront #-}
clear :: (PrimMonad m, VGM.MVector v a) => MVector v n (PrimState m) a -> m ()
clear (MVector v) = VGM.clear v
{-# inline clear #-}
read :: forall v n m a. (KnownNat n, PrimMonad m, VGM.MVector v a)
=> MVector v n (PrimState m) a -> Finite n -> m a
read (MVector v) i = v `VGM.unsafeRead` fromIntegral i
{-# inline read #-}
read' :: forall v n k a m p. (KnownNat n, KnownNat k, PrimMonad m, VGM.MVector v a)
=> MVector v (n+k+1) (PrimState m) a -> p k -> m a
read' (MVector v) p = v `VGM.unsafeRead` fromInteger (natVal p)
{-# inline read' #-}
unsafeRead :: forall v n a m. (KnownNat n, PrimMonad m, VGM.MVector v a)
=> MVector v n (PrimState m) a -> Int -> m a
unsafeRead (MVector v) i = v `VGM.unsafeRead` i
{-# inline unsafeRead #-}
write :: forall v n m a. (KnownNat n, PrimMonad m, VGM.MVector v a)
=> MVector v n (PrimState m) a -> Finite n -> a -> m ()
write (MVector v) i = VGM.unsafeWrite v (fromIntegral i)
{-# inline write #-}
write' :: forall v n k a m p. (KnownNat n, KnownNat k, PrimMonad m, VGM.MVector v a)
=> MVector v (n+k+1) (PrimState m) a -> p k -> a -> m ()
write' (MVector v) p = VGM.unsafeWrite v (fromInteger (natVal p))
{-# inline write' #-}
unsafeWrite :: forall v n m a. (KnownNat n, PrimMonad m, VGM.MVector v a)
=> MVector v n (PrimState m) a -> Int -> a -> m ()
unsafeWrite (MVector v) = VGM.unsafeWrite v
{-# inline unsafeWrite #-}
modify :: forall v n m a. (KnownNat n, PrimMonad m, VGM.MVector v a)
=> MVector v n (PrimState m) a -> (a -> a) -> Finite n -> m ()
modify (MVector v) f i = VGM.unsafeModify v f (fromIntegral i)
{-# inline modify #-}
modify' :: forall v n k a m p. (KnownNat n, KnownNat k, PrimMonad m, VGM.MVector v a)
=> MVector v (n+k+1) (PrimState m) a -> (a -> a) -> p k -> m ()
modify' (MVector v) f p = VGM.unsafeModify v f (fromInteger (natVal p))
{-# inline modify' #-}
unsafeModify :: forall v n m a. (KnownNat n, PrimMonad m, VGM.MVector v a)
=> MVector v n (PrimState m) a -> (a -> a) -> Int -> m ()
unsafeModify (MVector v) = VGM.unsafeModify v
{-# inline unsafeModify #-}
swap :: forall v n m a. (KnownNat n, PrimMonad m, VGM.MVector v a)
=> MVector v n (PrimState m) a -> Finite n -> Finite n -> m ()
swap (MVector v) i j = VGM.unsafeSwap v (fromIntegral i) (fromIntegral j)
{-# inline swap #-}
unsafeSwap :: forall v n m a. (KnownNat n, PrimMonad m, VGM.MVector v a)
=> MVector v n (PrimState m) a -> Int -> Int -> m ()
unsafeSwap (MVector v) = VGM.unsafeSwap v
{-# inline unsafeSwap #-}
exchange :: forall v n m a. (KnownNat n, PrimMonad m, VGM.MVector v a)
=> MVector v n (PrimState m) a -> Finite n -> a -> m a
exchange (MVector v) i = VGM.unsafeExchange v (fromIntegral i)
{-# inline exchange #-}
exchange' :: forall v n k a m p. (KnownNat n, KnownNat k, PrimMonad m, VGM.MVector v a)
=> MVector v (n+k+1) (PrimState m) a -> p k -> a -> m a
exchange' (MVector v) p = VGM.unsafeExchange v (fromInteger (natVal p))
{-# inline exchange' #-}
unsafeExchange :: forall v n m a. (KnownNat n, PrimMonad m, VGM.MVector v a)
=> MVector v n (PrimState m) a -> Int -> a -> m a
unsafeExchange (MVector v) = VGM.unsafeExchange v
{-# inline unsafeExchange #-}
#if MIN_VERSION_vector(0,12,0)
nextPermutation :: forall v n e m. (KnownNat n, Ord e, PrimMonad m, VGM.MVector v e)
=> MVector v n (PrimState m) e -> m Bool
nextPermutation (MVector v) = VGM.nextPermutation v
{-# inline nextPermutation #-}
#endif
set :: (PrimMonad m, VGM.MVector v a) => MVector v n (PrimState m) a -> a -> m ()
set (MVector v) = VGM.set v
{-# inline set #-}
copy :: (PrimMonad m, VGM.MVector v a)
=> MVector v n (PrimState m) a
-> MVector v n (PrimState m) a
-> m ()
copy (MVector v) (MVector u)
| v `VGM.overlaps` u = error "copy: overlapping vectors"
| otherwise = VGM.unsafeCopy v u
{-# inline copy #-}
unsafeCopy :: (PrimMonad m, VGM.MVector v a)
=> MVector v n (PrimState m) a
-> MVector v n (PrimState m) a
-> m ()
unsafeCopy (MVector v) (MVector u) = VGM.unsafeCopy v u
{-# inline unsafeCopy #-}
move :: (PrimMonad m, VGM.MVector v a)
=> MVector v n (PrimState m) a
-> MVector v n (PrimState m) a
-> m ()
move (MVector v) (MVector u) = VGM.unsafeMove v u
{-# inline move #-}
toSized :: forall v n s a. (VGM.MVector v a, KnownNat n)
=> v s a -> Maybe (MVector v n s a)
toSized v
| n' == fromIntegral (VGM.length v) = Just (MVector v)
| otherwise = Nothing
where n' = natVal (Proxy :: Proxy n)
{-# inline toSized #-}
withSized :: forall v s a r. VGM.MVector v a
=> v s a -> (forall n. KnownNat n => MVector v n s a -> r) -> r
withSized v f = case someNatVal (fromIntegral (VGM.length v)) of
Just (SomeNat (Proxy :: Proxy n)) -> f (MVector v :: MVector v n s a)
Nothing -> error "withSized: VGM.length returned negative length."
fromSized :: MVector v n s a -> v s a
fromSized (MVector v) = v
{-# inline fromSized #-}