    module Data.Array.Repa.Repr.Vector
            ( V, Array (..)
            , computeVectorS,  computeVectorP
            , fromListVector
            , fromVector
            , toVector)
    where
    import Data.Array.Repa.Shape
    import Data.Array.Repa.Base
    import Data.Array.Repa.Eval
    import qualified Data.Vector            as V
    import qualified Data.Vector.Mutable    as VM
    import Control.Monad

    -- | Arrays represented as boxed vectors.
    --
    --   This representation should only be used when your element type doesn't
    --   have an `Unbox` instsance. If it does, then use the Unboxed `U`
    --   representation will be faster.
    data V

    -- | Read elements from a boxed vector array.
    instance Source V a where
     data Array V sh a
            = AVector !sh !(V.Vector a)

     linearIndex :: Array V sh a -> Int -> a
    linearIndex (AVector _ vec) ix :: Int
    ix
            = Vector a
    vec Vector a -> Int -> a
    forall a. Vector a -> Int -> a
    V.! Int
    ix
     {-# INLINE linearIndex #-}

     unsafeLinearIndex :: Array V sh a -> Int -> a
    unsafeLinearIndex (AVector _ vec) ix :: Int
    ix
            = Vector a
    vec Vector a -> Int -> a
    forall a. Vector a -> Int -> a
    `V.unsafeIndex` Int
    ix
     {-# INLINE unsafeLinearIndex #-}

     extent :: Array V sh a -> sh
    extent (AVector sh _)
            = sh
    sh
     {-# INLINE extent #-}

     deepSeqArray :: Array V sh a -> b -> b
    deepSeqArray (AVector sh vec) x :: b
    x
      = sh
    sh sh -> b -> b
    forall sh a. Shape sh => sh -> a -> a
    `deepSeq` Vector a
    vec Vector a -> b -> b
    forall a b. a -> b -> b
    `seq` b
    x
     {-# INLINE deepSeqArray #-}

    deriving instance (Show sh, Show e)
            => Show (Array V sh e)

    deriving instance (Read sh, Read e)
            => Read (Array V sh e)

    -- Fill -----------------------------------------------------------------------
    -- | Filling of boxed vector arrays.
    instance Target V e where
     data MVec V e
      = MVector (VM.IOVector e)

     newMVec :: Int -> IO (MVec V e)
    newMVec n :: Int
    n
      = (IOVector e -> MVec V e) -> IO (IOVector e) -> IO (MVec V e)
    forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
    liftM IOVector e -> MVec V e
    forall e. IOVector e -> MVec V e
    MVector (Int -> IO (MVector (PrimState IO) e)
    forall (m :: * -> *) a.
    PrimMonad m =>
    Int -> m (MVector (PrimState m) a)
    VM.new Int
    n)
     {-# INLINE newMVec #-}

     unsafeWriteMVec :: MVec V e -> Int -> e -> IO ()
    unsafeWriteMVec (MVector v) ix :: Int
    ix
      = MVector (PrimState IO) e -> Int -> e -> IO ()
    forall (m :: * -> *) a.
    PrimMonad m =>
    MVector (PrimState m) a -> Int -> a -> m ()
    VM.unsafeWrite IOVector e
    MVector (PrimState IO) e
    v Int
    ix
     {-# INLINE unsafeWriteMVec #-}

     unsafeFreezeMVec :: sh -> MVec V e -> IO (Array V sh e)
    unsafeFreezeMVec sh :: sh
    sh (MVector mvec)
      = do  Vector e
    vec     <- MVector (PrimState IO) e -> IO (Vector e)
    forall (m :: * -> *) a.
    PrimMonad m =>
    MVector (PrimState m) a -> m (Vector a)
    V.unsafeFreeze IOVector e
    MVector (PrimState IO) e
    mvec
            Array V sh e -> IO (Array V sh e)
    forall (m :: * -> *) a. Monad m => a -> m a
    return  (Array V sh e -> IO (Array V sh e))
    -> Array V sh e -> IO (Array V sh e)
    forall a b. (a -> b) -> a -> b
    $  sh -> Vector e -> Array V sh e
    forall sh a. sh -> Vector a -> Array V sh a
    AVector sh
    sh Vector e
    vec
     {-# INLINE unsafeFreezeMVec #-}

     deepSeqMVec :: MVec V e -> a -> a
    deepSeqMVec !MVec V e
    _vec x :: a
    x
      = a
    x
     {-# INLINE deepSeqMVec #-}

     touchMVec :: MVec V e -> IO ()
    touchMVec _
      = () -> IO ()
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
     {-# INLINE touchMVec #-}

    -- Conversions ----------------------------------------------------------------
    -- | Sequential computation of array elements.
    --
    --   * This is an alias for `compute` with a more specific type.
    --
    computeVectorS
            :: Load r1 sh e
            => Array r1 sh e -> Array V sh e
    computeVectorS :: Array r1 sh e -> Array V sh e
    computeVectorS   = Array r1 sh e -> Array V sh e
    forall r1 sh e r2.
    (Load r1 sh e, Target r2 e) =>
    Array r1 sh e -> Array r2 sh e
    computeS
    {-# INLINE computeVectorS #-}

    -- | Parallel computation of array elements.
    computeVectorP
            :: (Load r1 sh e, Monad m)
            => Array r1 sh e -> m (Array V sh e)
    computeVectorP :: Array r1 sh e -> m (Array V sh e)
    computeVectorP   = Array r1 sh e -> m (Array V sh e)
    forall r1 sh e r2 (m :: * -> *).
    (Load r1 sh e, Target r2 e, Source r2 e, Monad m) =>
    Array r1 sh e -> m (Array r2 sh e)
    computeP
    {-# INLINE computeVectorP #-}

    -- | O(n). Convert a list to a boxed vector array.
    --
    --   * This is an alias for `fromList` with a more specific type.
    --
    fromListVector :: Shape sh => sh -> [a] -> Array V sh a
    fromListVector :: sh -> [a] -> Array V sh a
    fromListVector  = sh -> [a] -> Array V sh a
    forall sh r e. (Shape sh, Target r e) => sh -> [e] -> Array r sh e
    fromList
    {-# INLINE fromListVector #-}

    -- | O(1). Wrap a boxed vector as an array.
    fromVector :: sh -> V.Vector e -> Array V sh e
    fromVector :: sh -> Vector e -> Array V sh e
    fromVector sh :: sh
    sh vec :: Vector e
    vec
            = sh -> Vector e -> Array V sh e
    forall sh a. sh -> Vector a -> Array V sh a
    AVector sh
    sh Vector e
    vec
    {-# INLINE fromVector #-}

    -- | O(1). Unpack a boxed vector from an array.
    toVector   :: Array V sh e -> V.Vector e
    toVector :: Array V sh e -> Vector e
    toVector (AVector _ vec)
            = Vector e
    vec
    {-# INLINE toVector #-}