{-# LANGUAGE CPP, Rank2Types, MultiParamTypeClasses, FlexibleContexts,
             TypeFamilies, ScopedTypeVariables, BangPatterns #-}
-- |
-- Module      : Data.Vector.Generic
-- Copyright   : (c) Roman Leshchinskiy 2008-2010
-- License     : BSD-style
--
-- Maintainer  : Roman Leshchinskiy <rl@cse.unsw.edu.au>
-- Stability   : experimental
-- Portability : non-portable
--
-- Generic interface to pure vectors.
--

module Data.Vector.Generic (
  -- * Immutable vectors
  Vector(..), Mutable,

  -- * Accessors

  -- ** Length information
  length, null,

  -- ** Indexing
  (!), (!?), head, last,
  unsafeIndex, unsafeHead, unsafeLast,

  -- ** Monadic indexing
  indexM, headM, lastM,
  unsafeIndexM, unsafeHeadM, unsafeLastM,

  -- ** Extracting subvectors (slicing)
  slice, init, tail, take, drop, splitAt,
  unsafeSlice, unsafeInit, unsafeTail, unsafeTake, unsafeDrop,

  -- * Construction

  -- ** Initialisation
  empty, singleton, replicate, generate, iterateN,

  -- ** Monadic initialisation
  replicateM, generateM, iterateNM, create, createT,

  -- ** Unfolding
  unfoldr, unfoldrN,
  unfoldrM, unfoldrNM,
  constructN, constructrN,

  -- ** Enumeration
  enumFromN, enumFromStepN, enumFromTo, enumFromThenTo,

  -- ** Concatenation
  cons, snoc, (++), concat, concatNE,

  -- ** Restricting memory usage
  force,

  -- * Modifying vectors

  -- ** Bulk updates
  (//), update, update_,
  unsafeUpd, unsafeUpdate, unsafeUpdate_,

  -- ** Accumulations
  accum, accumulate, accumulate_,
  unsafeAccum, unsafeAccumulate, unsafeAccumulate_,

  -- ** Permutations
  reverse, backpermute, unsafeBackpermute,

  -- ** Safe destructive updates
  modify,

  -- * Elementwise operations

  -- ** Indexing
  indexed,

  -- ** Mapping
  map, imap, concatMap,

  -- ** Monadic mapping
  mapM, imapM, mapM_, imapM_, forM, forM_,

  -- ** Zipping
  zipWith, zipWith3, zipWith4, zipWith5, zipWith6,
  izipWith, izipWith3, izipWith4, izipWith5, izipWith6,
  zip, zip3, zip4, zip5, zip6,

  -- ** Monadic zipping
  zipWithM, izipWithM, zipWithM_, izipWithM_,

  -- ** Unzipping
  unzip, unzip3, unzip4, unzip5, unzip6,

  -- * Working with predicates

  -- ** Filtering
  filter, ifilter, uniq,
  mapMaybe, imapMaybe,
  filterM,
  takeWhile, dropWhile,

  -- ** Partitioning
  partition, partitionWith, unstablePartition, span, break,

  -- ** Searching
  elem, notElem, find, findIndex, findIndices, elemIndex, elemIndices,

  -- * Folding
  foldl, foldl1, foldl', foldl1', foldr, foldr1, foldr', foldr1',
  ifoldl, ifoldl', ifoldr, ifoldr',

  -- ** Specialised folds
  all, any, and, or,
  sum, product,
  maximum, maximumBy, minimum, minimumBy,
  minIndex, minIndexBy, maxIndex, maxIndexBy,

  -- ** Monadic folds
  foldM, ifoldM, foldM', ifoldM',
  fold1M, fold1M', foldM_, ifoldM_,
  foldM'_, ifoldM'_, fold1M_, fold1M'_,

  -- ** Monadic sequencing
  sequence, sequence_,

  -- * Prefix sums (scans)
  prescanl, prescanl',
  postscanl, postscanl',
  scanl, scanl', scanl1, scanl1',
  iscanl, iscanl',
  prescanr, prescanr',
  postscanr, postscanr',
  scanr, scanr', scanr1, scanr1',
  iscanr, iscanr',

  -- * Conversions

  -- ** Lists
  toList, fromList, fromListN,

  -- ** Different vector types
  convert,

  -- ** Mutable vectors
  freeze, thaw, copy, unsafeFreeze, unsafeThaw, unsafeCopy,

  -- * Fusion support

  -- ** Conversion to/from Bundles
  stream, unstream, streamR, unstreamR,

  -- ** Recycling support
  new, clone,

  -- * Utilities

  -- ** Comparisons
  eq, cmp,
  eqBy, cmpBy,

  -- ** Show and Read
  showsPrec, readPrec,
  liftShowsPrec, liftReadsPrec,

  -- ** @Data@ and @Typeable@
  gfoldl, gunfold, dataCast, mkVecType, mkVecConstr, mkType
) where

import           Data.Vector.Generic.Base

import qualified Data.Vector.Generic.Mutable as M

import qualified Data.Vector.Generic.New as New
import           Data.Vector.Generic.New ( New )

import qualified Data.Vector.Fusion.Bundle as Bundle
import           Data.Vector.Fusion.Bundle ( Bundle, MBundle, lift, inplace )
import qualified Data.Vector.Fusion.Bundle.Monadic as MBundle
import           Data.Vector.Fusion.Stream.Monadic ( Stream )
import qualified Data.Vector.Fusion.Stream.Monadic as S
import           Data.Vector.Fusion.Bundle.Size
import           Data.Vector.Fusion.Util

import Control.Monad.ST ( ST, runST )
import Control.Monad.Primitive
import Prelude hiding ( length, null,
                        replicate, (++), concat,
                        head, last,
                        init, tail, take, drop, splitAt, reverse,
                        map, concat, concatMap,
                        zipWith, zipWith3, zip, zip3, unzip, unzip3,
                        filter, takeWhile, dropWhile, span, break,
                        elem, notElem,
                        foldl, foldl1, foldr, foldr1,
                        all, any, and, or, sum, product, maximum, minimum,
                        scanl, scanl1, scanr, scanr1,
                        enumFromTo, enumFromThenTo,
                        mapM, mapM_, sequence, sequence_,
                        showsPrec )

import qualified Text.Read as Read
import qualified Data.List.NonEmpty as NonEmpty

#if __GLASGOW_HASKELL__ >= 707
import Data.Typeable ( Typeable, gcast1 )
#else
import Data.Typeable ( Typeable1, gcast1 )
#endif

#include "vector.h"

import Data.Data ( Data, DataType, Constr, Fixity(Prefix),
                   mkDataType, mkConstr, constrIndex,
#if MIN_VERSION_base(4,2,0)
                   mkNoRepType )
#else
                   mkNorepType )
#endif
import qualified Data.Traversable as T (Traversable(mapM))

#if !MIN_VERSION_base(4,2,0)
mkNoRepType :: String -> DataType
mkNoRepType = mkNorepType
#endif

-- Length information
-- ------------------

-- | /O(1)/ Yield the length of the vector
length :: Vector v a => v a -> Int
{-# INLINE length #-}
length :: v a -> Int
length = Bundle v a -> Int
forall (v :: * -> *) a. Bundle v a -> Int
Bundle.length (Bundle v a -> Int) -> (v a -> Bundle v a) -> v a -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. v a -> Bundle v a
forall (v :: * -> *) a. Vector v a => v a -> Bundle v a
stream'

-- | /O(1)/ Test whether a vector is empty
null :: Vector v a => v a -> Bool
{-# INLINE null #-}
null :: v a -> Bool
null = Bundle v a -> Bool
forall (v :: * -> *) a. Bundle v a -> Bool
Bundle.null (Bundle v a -> Bool) -> (v a -> Bundle v a) -> v a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. v a -> Bundle v a
forall (v :: * -> *) a. Vector v a => v a -> Bundle v a
stream

-- Indexing
-- --------

infixl 9 !
-- | O(1) Indexing
(!) :: Vector v a => v a -> Int -> a
{-# INLINE_FUSED (!) #-}
(!) v :: v a
v i :: Int
i = BOUNDS_CHECK(checkIndex) "(!)" i (length v)
        (a -> a) -> a -> a
forall a b. (a -> b) -> a -> b
$ Id a -> a
forall a. Id a -> a
unId (v a -> Int -> Id a
forall (v :: * -> *) a (m :: * -> *).
(Vector v a, Monad m) =>
v a -> Int -> m a
basicUnsafeIndexM v a
v Int
i)

infixl 9 !?
-- | O(1) Safe indexing
(!?) :: Vector v a => v a -> Int -> Maybe a
{-# INLINE_FUSED (!?) #-}
v :: v a
v !? :: v a -> Int -> Maybe a
!? i :: Int
i | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< 0 Bool -> Bool -> Bool
|| Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= v a -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
length v a
v = Maybe a
forall a. Maybe a
Nothing
       | Bool
otherwise              = a -> Maybe a
forall a. a -> Maybe a
Just (a -> Maybe a) -> a -> Maybe a
forall a b. (a -> b) -> a -> b
$ v a -> Int -> a
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
unsafeIndex v a
v Int
i

-- | /O(1)/ First element
head :: Vector v a => v a -> a
{-# INLINE_FUSED head #-}
head :: v a -> a
head v :: v a
v = v a
v v a -> Int -> a
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
! 0

-- | /O(1)/ Last element
last :: Vector v a => v a -> a
{-# INLINE_FUSED last #-}
last :: v a -> a
last v :: v a
v = v a
v v a -> Int -> a
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
! (v a -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
length v a
v Int -> Int -> Int
forall a. Num a => a -> a -> a
- 1)

-- | /O(1)/ Unsafe indexing without bounds checking
unsafeIndex :: Vector v a => v a -> Int -> a
{-# INLINE_FUSED unsafeIndex #-}
unsafeIndex :: v a -> Int -> a
unsafeIndex v :: v a
v i :: Int
i = UNSAFE_CHECK(checkIndex) "unsafeIndex" i (length v)
                (a -> a) -> a -> a
forall a b. (a -> b) -> a -> b
$ Id a -> a
forall a. Id a -> a
unId (v a -> Int -> Id a
forall (v :: * -> *) a (m :: * -> *).
(Vector v a, Monad m) =>
v a -> Int -> m a
basicUnsafeIndexM v a
v Int
i)

-- | /O(1)/ First element without checking if the vector is empty
unsafeHead :: Vector v a => v a -> a
{-# INLINE_FUSED unsafeHead #-}
unsafeHead :: v a -> a
unsafeHead v :: v a
v = v a -> Int -> a
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
unsafeIndex v a
v 0

-- | /O(1)/ Last element without checking if the vector is empty
unsafeLast :: Vector v a => v a -> a
{-# INLINE_FUSED unsafeLast #-}
unsafeLast :: v a -> a
unsafeLast v :: v a
v = v a -> Int -> a
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
unsafeIndex v a
v (v a -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
length v a
v Int -> Int -> Int
forall a. Num a => a -> a -> a
- 1)

{-# RULES

"(!)/unstream [Vector]" forall i s.
  new (New.unstream s) ! i = s Bundle.!! i

"(!?)/unstream [Vector]" forall i s.
  new (New.unstream s) !? i = s Bundle.!? i

"head/unstream [Vector]" forall s.
  head (new (New.unstream s)) = Bundle.head s

"last/unstream [Vector]" forall s.
  last (new (New.unstream s)) = Bundle.last s

"unsafeIndex/unstream [Vector]" forall i s.
  unsafeIndex (new (New.unstream s)) i = s Bundle.!! i

"unsafeHead/unstream [Vector]" forall s.
  unsafeHead (new (New.unstream s)) = Bundle.head s

"unsafeLast/unstream [Vector]" forall s.
  unsafeLast (new (New.unstream s)) = Bundle.last s  #-}



-- Monadic indexing
-- ----------------

-- | /O(1)/ Indexing in a monad.
--
-- The monad allows operations to be strict in the vector when necessary.
-- Suppose vector copying is implemented like this:
--
-- > copy mv v = ... write mv i (v ! i) ...
--
-- For lazy vectors, @v ! i@ would not be evaluated which means that @mv@
-- would unnecessarily retain a reference to @v@ in each element written.
--
-- With 'indexM', copying can be implemented like this instead:
--
-- > copy mv v = ... do
-- >                   x <- indexM v i
-- >                   write mv i x
--
-- Here, no references to @v@ are retained because indexing (but /not/ the
-- elements) is evaluated eagerly.
--
indexM :: (Vector v a, Monad m) => v a -> Int -> m a
{-# INLINE_FUSED indexM #-}
indexM :: v a -> Int -> m a
indexM v :: v a
v i :: Int
i = BOUNDS_CHECK(checkIndex) "indexM" i (length v)
           (m a -> m a) -> m a -> m a
forall a b. (a -> b) -> a -> b
$ v a -> Int -> m a
forall (v :: * -> *) a (m :: * -> *).
(Vector v a, Monad m) =>
v a -> Int -> m a
basicUnsafeIndexM v a
v Int
i

-- | /O(1)/ First element of a vector in a monad. See 'indexM' for an
-- explanation of why this is useful.
headM :: (Vector v a, Monad m) => v a -> m a
{-# INLINE_FUSED headM #-}
headM :: v a -> m a
headM v :: v a
v = v a -> Int -> m a
forall (v :: * -> *) a (m :: * -> *).
(Vector v a, Monad m) =>
v a -> Int -> m a
indexM v a
v 0

-- | /O(1)/ Last element of a vector in a monad. See 'indexM' for an
-- explanation of why this is useful.
lastM :: (Vector v a, Monad m) => v a -> m a
{-# INLINE_FUSED lastM #-}
lastM :: v a -> m a
lastM v :: v a
v = v a -> Int -> m a
forall (v :: * -> *) a (m :: * -> *).
(Vector v a, Monad m) =>
v a -> Int -> m a
indexM v a
v (v a -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
length v a
v Int -> Int -> Int
forall a. Num a => a -> a -> a
- 1)

-- | /O(1)/ Indexing in a monad without bounds checks. See 'indexM' for an
-- explanation of why this is useful.
unsafeIndexM :: (Vector v a, Monad m) => v a -> Int -> m a
{-# INLINE_FUSED unsafeIndexM #-}
unsafeIndexM :: v a -> Int -> m a
unsafeIndexM v :: v a
v i :: Int
i = UNSAFE_CHECK(checkIndex) "unsafeIndexM" i (length v)
                 (m a -> m a) -> m a -> m a
forall a b. (a -> b) -> a -> b
$ v a -> Int -> m a
forall (v :: * -> *) a (m :: * -> *).
(Vector v a, Monad m) =>
v a -> Int -> m a
basicUnsafeIndexM v a
v Int
i

-- | /O(1)/ First element in a monad without checking for empty vectors.
-- See 'indexM' for an explanation of why this is useful.
unsafeHeadM :: (Vector v a, Monad m) => v a -> m a
{-# INLINE_FUSED unsafeHeadM #-}
unsafeHeadM :: v a -> m a
unsafeHeadM v :: v a
v = v a -> Int -> m a
forall (v :: * -> *) a (m :: * -> *).
(Vector v a, Monad m) =>
v a -> Int -> m a
unsafeIndexM v a
v 0

-- | /O(1)/ Last element in a monad without checking for empty vectors.
-- See 'indexM' for an explanation of why this is useful.
unsafeLastM :: (Vector v a, Monad m) => v a -> m a
{-# INLINE_FUSED unsafeLastM #-}
unsafeLastM :: v a -> m a
unsafeLastM v :: v a
v = v a -> Int -> m a
forall (v :: * -> *) a (m :: * -> *).
(Vector v a, Monad m) =>
v a -> Int -> m a
unsafeIndexM v a
v (v a -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
length v a
v Int -> Int -> Int
forall a. Num a => a -> a -> a
- 1)

{-# RULES

"indexM/unstream [Vector]" forall s i.
  indexM (new (New.unstream s)) i = lift s MBundle.!! i

"headM/unstream [Vector]" forall s.
  headM (new (New.unstream s)) = MBundle.head (lift s)

"lastM/unstream [Vector]" forall s.
  lastM (new (New.unstream s)) = MBundle.last (lift s)

"unsafeIndexM/unstream [Vector]" forall s i.
  unsafeIndexM (new (New.unstream s)) i = lift s MBundle.!! i

"unsafeHeadM/unstream [Vector]" forall s.
  unsafeHeadM (new (New.unstream s)) = MBundle.head (lift s)

"unsafeLastM/unstream [Vector]" forall s.
  unsafeLastM (new (New.unstream s)) = MBundle.last (lift s)   #-}



-- Extracting subvectors (slicing)
-- -------------------------------

-- | /O(1)/ Yield a slice of the vector without copying it. The vector must
-- contain at least @i+n@ elements.
slice :: Vector v a => Int   -- ^ @i@ starting index
                    -> Int   -- ^ @n@ length
                    -> v a
                    -> v a
{-# INLINE_FUSED slice #-}
slice :: Int -> Int -> v a -> v a
slice i :: Int
i n :: Int
n v :: v a
v = BOUNDS_CHECK(checkSlice) "slice" i n (length v)
            (v a -> v a) -> v a -> v a
forall a b. (a -> b) -> a -> b
$ Int -> Int -> v a -> v a
forall (v :: * -> *) a. Vector v a => Int -> Int -> v a -> v a
basicUnsafeSlice Int
i Int
n v a
v

-- | /O(1)/ Yield all but the last element without copying. The vector may not
-- be empty.
init :: Vector v a => v a -> v a
{-# INLINE_FUSED init #-}
init :: v a -> v a
init v :: v a
v = Int -> Int -> v a -> v a
forall (v :: * -> *) a. Vector v a => Int -> Int -> v a -> v a
slice 0 (v a -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
length v a
v Int -> Int -> Int
forall a. Num a => a -> a -> a
- 1) v a
v

-- | /O(1)/ Yield all but the first element without copying. The vector may not
-- be empty.
tail :: Vector v a => v a -> v a
{-# INLINE_FUSED tail #-}
tail :: v a -> v a
tail v :: v a
v = Int -> Int -> v a -> v a
forall (v :: * -> *) a. Vector v a => Int -> Int -> v a -> v a
slice 1 (v a -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
length v a
v Int -> Int -> Int
forall a. Num a => a -> a -> a
- 1) v a
v

-- | /O(1)/ Yield the first @n@ elements without copying. The vector may
-- contain less than @n@ elements in which case it is returned unchanged.
take :: Vector v a => Int -> v a -> v a
{-# INLINE_FUSED take #-}
take :: Int -> v a -> v a
take n :: Int
n v :: v a
v = Int -> Int -> v a -> v a
forall (v :: * -> *) a. Vector v a => Int -> Int -> v a -> v a
unsafeSlice 0 ((Int -> Int -> Int) -> Int -> Int -> Int
forall a b. (a -> b) -> a -> b
delay_inline Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
n' (v a -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
length v a
v)) v a
v
  where n' :: Int
n' = Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
n 0

-- | /O(1)/ Yield all but the first @n@ elements without copying. The vector may
-- contain less than @n@ elements in which case an empty vector is returned.
drop :: Vector v a => Int -> v a -> v a
{-# INLINE_FUSED drop #-}
drop :: Int -> v a -> v a
drop n :: Int
n v :: v a
v = Int -> Int -> v a -> v a
forall (v :: * -> *) a. Vector v a => Int -> Int -> v a -> v a
unsafeSlice ((Int -> Int -> Int) -> Int -> Int -> Int
forall a b. (a -> b) -> a -> b
delay_inline Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
n' Int
len)
                       ((Int -> Int -> Int) -> Int -> Int -> Int
forall a b. (a -> b) -> a -> b
delay_inline Int -> Int -> Int
forall a. Ord a => a -> a -> a
max 0 (Int
len Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
n')) v a
v
  where n' :: Int
n' = Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
n 0
        len :: Int
len = v a -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
length v a
v

-- | /O(1)/ Yield the first @n@ elements paired with the remainder without copying.
--
-- Note that @'splitAt' n v@ is equivalent to @('take' n v, 'drop' n v)@
-- but slightly more efficient.
{-# INLINE_FUSED splitAt #-}
splitAt :: Vector v a => Int -> v a -> (v a, v a)
splitAt :: Int -> v a -> (v a, v a)
splitAt n :: Int
n v :: v a
v = ( Int -> Int -> v a -> v a
forall (v :: * -> *) a. Vector v a => Int -> Int -> v a -> v a
unsafeSlice 0 Int
m v a
v
              , Int -> Int -> v a -> v a
forall (v :: * -> *) a. Vector v a => Int -> Int -> v a -> v a
unsafeSlice Int
m ((Int -> Int -> Int) -> Int -> Int -> Int
forall a b. (a -> b) -> a -> b
delay_inline Int -> Int -> Int
forall a. Ord a => a -> a -> a
max 0 (Int
len Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
n')) v a
v
              )
    where
      m :: Int
m   = (Int -> Int -> Int) -> Int -> Int -> Int
forall a b. (a -> b) -> a -> b
delay_inline Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
n' Int
len
      n' :: Int
n'  = Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
n 0
      len :: Int
len = v a -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
length v a
v

-- | /O(1)/ Yield a slice of the vector without copying. The vector must
-- contain at least @i+n@ elements but this is not checked.
unsafeSlice :: Vector v a => Int   -- ^ @i@ starting index
                          -> Int   -- ^ @n@ length
                          -> v a
                          -> v a
{-# INLINE_FUSED unsafeSlice #-}
unsafeSlice :: Int -> Int -> v a -> v a
unsafeSlice i :: Int
i n :: Int
n v :: v a
v = UNSAFE_CHECK(checkSlice) "unsafeSlice" i n (length v)
                  (v a -> v a) -> v a -> v a
forall a b. (a -> b) -> a -> b
$ Int -> Int -> v a -> v a
forall (v :: * -> *) a. Vector v a => Int -> Int -> v a -> v a
basicUnsafeSlice Int
i Int
n v a
v

-- | /O(1)/ Yield all but the last element without copying. The vector may not
-- be empty but this is not checked.
unsafeInit :: Vector v a => v a -> v a
{-# INLINE_FUSED unsafeInit #-}
unsafeInit :: v a -> v a
unsafeInit v :: v a
v = Int -> Int -> v a -> v a
forall (v :: * -> *) a. Vector v a => Int -> Int -> v a -> v a
unsafeSlice 0 (v a -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
length v a
v Int -> Int -> Int
forall a. Num a => a -> a -> a
- 1) v a
v

-- | /O(1)/ Yield all but the first element without copying. The vector may not
-- be empty but this is not checked.
unsafeTail :: Vector v a => v a -> v a
{-# INLINE_FUSED unsafeTail #-}
unsafeTail :: v a -> v a
unsafeTail v :: v a
v = Int -> Int -> v a -> v a
forall (v :: * -> *) a. Vector v a => Int -> Int -> v a -> v a
unsafeSlice 1 (v a -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
length v a
v Int -> Int -> Int
forall a. Num a => a -> a -> a
- 1) v a
v

-- | /O(1)/ Yield the first @n@ elements without copying. The vector must
-- contain at least @n@ elements but this is not checked.
unsafeTake :: Vector v a => Int -> v a -> v a
{-# INLINE unsafeTake #-}
unsafeTake :: Int -> v a -> v a
unsafeTake n :: Int
n v :: v a
v = Int -> Int -> v a -> v a
forall (v :: * -> *) a. Vector v a => Int -> Int -> v a -> v a
unsafeSlice 0 Int
n v a
v

-- | /O(1)/ Yield all but the first @n@ elements without copying. The vector
-- must contain at least @n@ elements but this is not checked.
unsafeDrop :: Vector v a => Int -> v a -> v a
{-# INLINE unsafeDrop #-}
unsafeDrop :: Int -> v a -> v a
unsafeDrop n :: Int
n v :: v a
v = Int -> Int -> v a -> v a
forall (v :: * -> *) a. Vector v a => Int -> Int -> v a -> v a
unsafeSlice Int
n (v a -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
length v a
v Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
n) v a
v


-- Turned off due to: https://github.com/haskell/vector/issues/257
-- "slice/new [Vector]" forall i n p.
--   slice i n (new p) = new (New.slice i n p)

{-# RULES

"init/new [Vector]" forall p.
  init (new p) = new (New.init p)

"tail/new [Vector]" forall p.
  tail (new p) = new (New.tail p)

"take/new [Vector]" forall n p.
  take n (new p) = new (New.take n p)

"drop/new [Vector]" forall n p.
  drop n (new p) = new (New.drop n p)

"unsafeSlice/new [Vector]" forall i n p.
  unsafeSlice i n (new p) = new (New.unsafeSlice i n p)

"unsafeInit/new [Vector]" forall p.
  unsafeInit (new p) = new (New.unsafeInit p)

"unsafeTail/new [Vector]" forall p.
  unsafeTail (new p) = new (New.unsafeTail