    {-# LANGUAGE CPP #-}
    {-# LANGUAGE TypeFamilies #-}
    {-# LANGUAGE MultiParamTypeClasses #-}
    -----------------------------------------------------------------------------
    -- |
    -- Module      :  Data.Vector.Instances
    -- Copyright   :  (c) Edward Kmett 2010
    -- License     :  BSD3
    -- Maintainer  :  ekmett@gmail.com
    -- Stability   :  experimental
    -- Portability :  portable
    --
    -----------------------------------------------------------------------------

    module Data.Vector.Instances () where

    import Prelude hiding ((++), drop, length)
    import Control.Applicative
    import Control.Monad
    import Data.Semigroup
    #ifdef MIN_VERSION_hashable
    import Data.Hashable (Hashable(..))
    import Data.Hashable.Lifted (Hashable1(..))
    #endif
    import Data.Key
    import Data.Functor.Bind
    import Data.Functor.Extend
    import Data.Functor.Plus
    import Data.Pointed
    import Data.Monoid (Monoid(..))
    import qualified Data.Vector as Vector
    import qualified Data.Vector.Generic as G
    #if MIN_VERSION_vector(0,11,0)
    import qualified Data.Vector.Fusion.Bundle as Stream
    import Data.Vector.Fusion.Bundle.Size
    #else
    import qualified Data.Vector.Fusion.Stream as Stream
    import Data.Vector.Fusion.Stream.Size
    #endif
    import Data.Vector (Vector,(++),drop,length,imap,ifoldr, ifoldl, izipWith,(!?),(//), generate)
    import qualified Data.Vector as Vector
    #if MIN_VERSION_vector(0,13,2)
    import qualified Data.Vector.Strict as Vector.Strict
    #endif
    import qualified Data.Vector.Unboxed as Unboxed
    import qualified Data.Vector.Storable as Storable
    import qualified Data.Vector.Primitive as Primitive

    type instance Key Vector = Int

    instance Keyed Vector where
      mapWithKey :: forall a b. (Key Vector -> a -> b) -> Vector a -> Vector b
    mapWithKey = (Int -> a -> b) -> Vector a -> Vector b
    (Key Vector -> a -> b) -> Vector a -> Vector b
    forall a b. (Int -> a -> b) -> Vector a -> Vector b
    Vector.imap
      {-# INLINE mapWithKey #-}

    instance Zip Vector where
      zipWith :: forall a b c. (a -> b -> c) -> Vector a -> Vector b -> Vector c
    zipWith = (a -> b -> c) -> Vector a -> Vector b -> Vector c
    forall a b c. (a -> b -> c) -> Vector a -> Vector b -> Vector c
    Vector.zipWith
      {-# INLINE zipWith #-}

    instance ZipWithKey Vector where
      zipWithKey :: forall a b c.
    (Key Vector -> a -> b -> c) -> Vector a -> Vector b -> Vector c
    zipWithKey = (Int -> a -> b -> c) -> Vector a -> Vector b -> Vector c
    (Key Vector -> a -> b -> c) -> Vector a -> Vector b -> Vector c
    forall a b c.
    (Int -> a -> b -> c) -> Vector a -> Vector b -> Vector c
    Vector.izipWith
      {-# INLINE zipWithKey #-}

    instance Indexable Vector where
      index :: forall a. Vector a -> Key Vector -> a
    index = Vector a -> Int -> a
    Vector a -> Key Vector -> a
    forall a. Vector a -> Int -> a
    (Vector.!)
      {-# INLINE index #-}

    instance Lookup Vector where
      lookup :: forall a. Key Vector -> Vector a -> Maybe a
    lookup = (Vector a -> Int -> Maybe a) -> Int -> Vector a -> Maybe a
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip Vector a -> Int -> Maybe a
    forall a. Vector a -> Int -> Maybe a
    (!?)
      {-# INLINE lookup #-}

    instance Adjustable Vector where
      adjust :: forall a. (a -> a) -> Key Vector -> Vector a -> Vector a
    adjust a -> a
    f Key Vector
    n Vector a
    v = case Vector a
    v Vector a -> Int -> Maybe a
    forall a. Vector a -> Int -> Maybe a
    !? Int
    Key Vector
    n of
        Just a
    a ->  Vector a
    v Vector a -> [(Int, a)] -> Vector a
    forall a. Vector a -> [(Int, a)] -> Vector a
    // [(Int
    Key Vector
    n, a -> a
    f a
    a)]
        Maybe a
    Nothing -> Vector a
    v
      {-# INLINE adjust #-}

      replace :: forall a. Key Vector -> a -> Vector a -> Vector a
    replace Key Vector
    n a
    a Vector a
    v = Vector a
    v Vector a -> [(Int, a)] -> Vector a
    forall a. Vector a -> [(Int, a)] -> Vector a
    // [(Int
    Key Vector
    n,a
    a)]
      {-# INLINE replace #-}

    instance FoldableWithKey Vector where
      foldrWithKey :: forall a b. (Key Vector -> a -> b -> b) -> b -> Vector a -> b
    foldrWithKey = (Int -> a -> b -> b) -> b -> Vector a -> b
    (Key Vector -> a -> b -> b) -> b -> Vector a -> b
    forall a b. (Int -> a -> b -> b) -> b -> Vector a -> b
    Vector.ifoldr
      {-# INLINE foldrWithKey #-}
      foldlWithKey :: forall b a. (b -> Key Vector -> a -> b) -> b -> Vector a -> b
    foldlWithKey = (b -> Int -> a -> b) -> b -> Vector a -> b
    (b -> Key Vector -> a -> b) -> b -> Vector a -> b
    forall a b. (a -> Int -> b -> a) -> a -> Vector b -> a
    Vector.ifoldl
      {-# INLINE foldlWithKey #-}

    instance Apply Vector where
      Vector (a -> b)
    fs <.> :: forall a b. Vector (a -> b) -> Vector a -> Vector b
    <.> Vector a
    as =
        Bundle Vector b -> Vector b
    forall (v :: * -> *) a. Vector v a => Bundle v a -> v a
    G.unstream (Bundle Vector b -> Vector b) -> Bundle Vector b -> Vector b
    forall a b. (a -> b) -> a -> b
    $ Bundle Vector b -> Size -> Bundle Vector b
    forall (v :: * -> *) a. Bundle v a -> Size -> Bundle v a
    Stream.sized Bundle Vector b
    results (Int -> Size
    Exact Int
    n)
        where
          n :: Int
    n = Vector (a -> b) -> Int
    forall a. Vector a -> Int
    Vector.length Vector (a -> b)
    fs Int -> Int -> Int
    forall a. Num a => a -> a -> a
    * Vector a -> Int
    forall a. Vector a -> Int
    Vector.length Vector a
    as
          results :: Bundle Vector b
    results = ((a -> b) -> Bundle Vector b)
    -> Bundle Vector (a -> b) -> Bundle Vector b
    forall a (v :: * -> *) b.
    (a -> Bundle v b) -> Bundle v a -> Bundle v b
    Stream.concatMap (a -> b) -> Bundle Vector b
    body (Bundle Vector (a -> b) -> Bundle Vector b)
    -> Bundle Vector (a -> b) -> Bundle Vector b
    forall a b. (a -> b) -> a -> b
    $ Vector (a -> b) -> Bundle Vector (a -> b)
    forall (v :: * -> *) a. Vector v a => v a -> Bundle v a
    G.stream Vector (a -> b)
    fs
          body :: (a -> b) -> Bundle Vector b
    body a -> b
    f = (a -> b) -> Bundle Vector a -> Bundle Vector b
    forall a b (v :: * -> *). (a -> b) -> Bundle v a -> Bundle v b
    Stream.map a -> b
    f (Bundle Vector a -> Bundle Vector b)
    -> Bundle Vector a -> Bundle Vector b
    forall a b. (a -> b) -> a -> b
    $ Vector a -> Bundle Vector a
    forall (v :: * -> *) a. Vector v a => v a -> Bundle v a
    G.stream Vector a
    as
      {-# INLINE (<.>) #-}

    instance Pointed Vector where
      point :: forall a. a -> Vector a
    point = a -> Vector a
    forall a. a -> Vector a
    Vector.singleton
      {-# INLINE point #-}

    instance Bind Vector where
      Vector a
    v >>- :: forall a b. Vector a -> (a -> Vector b) -> Vector b
    >>- a -> Vector b
    f = (a -> Vector b) -> Vector a -> Vector b
    forall a b. (a -> Vector b) -> Vector a -> Vector b
    Vector.concatMap a -> Vector b
    f Vector a
    v
      {-# INLINE (>>-) #-}

    instance Alt Vector where
      <!> :: forall a. Vector a -> Vector a -> Vector a
    (<!>) = Vector a -> Vector a -> Vector a
    forall a. Vector a -> Vector a -> Vector a
    (++)
      {-# INLINE (<!>) #-}

    instance Plus Vector where
      zero :: forall a. Vector a
    zero = Vector a
    forall a. Vector a
    Vector.empty
      {-# INLINE zero #-}

    instance TraversableWithKey Vector where
      traverseWithKey :: forall (f :: * -> *) a b.
    Applicative f =>
    (Key Vector -> a -> f b) -> Vector a -> f (Vector b)
    traverseWithKey Key Vector -> a -> f b
    f Vector a
    v
         = Int -> [b] -> Vector b
    forall a. Int -> [a] -> Vector a
    Vector.fromListN (Vector a -> Int
    forall a. Vector a -> Int
    Vector.length Vector a
    v) ([b] -> Vector b) -> f [b] -> f (Vector b)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Key [] -> a -> f b) -> [a] -> f [b]
    forall (t :: * -> *) (f :: * -> *) a b.
    (TraversableWithKey t, Applicative f) =>
    (Key t -> a -> f b) -> t a -> f (t b)
    forall (f :: * -> *) a b.
    Applicative f =>
    (Key [] -> a -> f b) -> [a] -> f [b]
    traverseWithKey Key [] -> a -> f b
    Key Vector -> a -> f b
    f (Vector a -> [a]
    forall a. Vector a -> [a]
    Vector.toList Vector a
    v)
      {-# INLINE traverseWithKey #-}

    instance Extend Vector where
      duplicated :: forall a. Vector a -> Vector (Vector a)
    duplicated Vector a
    v = Int -> (Int -> Vector a) -> Vector (Vector a)
    forall a. Int -> (Int -> a) -> Vector a
    generate (Vector a -> Int
    forall a. Vector a -> Int
    length Vector a
    v) (Int -> Vector a -> Vector a
    forall a. Int -> Vector a -> Vector a
    `drop` Vector a
    v)
      {-# INLINE duplicated #-}
      extended :: forall a b. (Vector a -> b) -> Vector a -> Vector b
    extended Vector a -> b
    f Vector a
    v = Int -> (Int -> b) -> Vector b
    forall a. Int -> (Int -> a) -> Vector a
    generate (Vector a -> Int
    forall a. Vector a -> Int
    length Vector a
    v) (\Int
    n -> Vector a -> b
    f (Int -> Vector a -> Vector a
    forall a. Int -> Vector a -> Vector a
    drop Int
    n Vector a
    v))
      {-# INLINE extended #-}

    #if !(MIN_VERSION_vector(0,12,0))
    instance Semigroup (Vector a) where
      (<>) = (++)
      {-# INLINE (<>) #-}

    instance Unboxed.Unbox a => Semigroup (Unboxed.Vector a) where
      (<>) = (Unboxed.++)
      {-# INLINE (<>) #-}

    instance Storable.Storable a => Semigroup (Storable.Vector a) where
      (<>) = (Storable.++)
      {-# INLINE (<>) #-}

    instance Primitive.Prim a => Semigroup (Primitive.Vector a) where
      (<>) = (Primitive.++)
      {-# INLINE (<>) #-}
    #endif

    #ifdef MIN_VERSION_hashable
    instance (Hashable a) => Hashable (Vector a) where
      hashWithSalt :: Int -> Vector a -> Int
    hashWithSalt Int
    salt = Int -> [a] -> Int
    forall a. Hashable a => Int -> a -> Int
    hashWithSalt Int
    salt ([a] -> Int) -> (Vector a -> [a]) -> Vector a -> Int
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Vector a -> [a]
    forall a. Vector a -> [a]
    Vector.toList
      {-# INLINE hashWithSalt #-}

    #if MIN_VERSION_vector(0,13,2)
    instance (Hashable a) => Hashable (Vector.Strict.Vector a) where
      hashWithSalt :: Int -> Vector a -> Int
    hashWithSalt Int
    salt = Int -> [a] -> Int
    forall a. Hashable a => Int -> a -> Int
    hashWithSalt Int
    salt ([a] -> Int) -> (Vector a -> [a]) -> Vector a -> Int
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Vector a -> [a]
    forall a. Vector a -> [a]
    Vector.Strict.toList
      {-# INLINE hashWithSalt #-}

    instance Hashable1 Vector.Strict.Vector where
      liftHashWithSalt :: forall a. (Int -> a -> Int) -> Int -> Vector a -> Int
    liftHashWithSalt Int -> a -> Int
    itemHashWithSalt Int
    salt = (Int -> a -> Int) -> Int -> [a] -> Int
    forall a. (Int -> a -> Int) -> Int -> [a] -> Int
    forall (t :: * -> *) a.
    Hashable1 t =>
    (Int -> a -> Int) -> Int -> t a -> Int
    liftHashWithSalt Int -> a -> Int
    itemHashWithSalt Int
    salt ([a] -> Int) -> (Vector a -> [a]) -> Vector a -> Int
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Vector a -> [a]
    forall a. Vector a -> [a]
    Vector.Strict.toList
      {-# INLINE liftHashWithSalt #-}
    #endif

    instance (Unboxed.Unbox a, Hashable a) => Hashable (Unboxed.Vector a) where
      hashWithSalt :: Int -> Vector a -> Int
    hashWithSalt Int
    salt = Int -> [a] -> Int
    forall a. Hashable a => Int -> a -> Int
    hashWithSalt Int
    salt ([a] -> Int) -> (Vector a -> [a]) -> Vector a -> Int
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Vector a -> [a]
    forall a. Unbox a => Vector a -> [a]
    Unboxed.toList
      {-# INLINE hashWithSalt #-}

    instance (Storable.Storable a, Hashable a) => Hashable (Storable.Vector a) where
      hashWithSalt :: Int -> Vector a -> Int
    hashWithSalt Int
    salt = Int -> [a] -> Int
    forall a. Hashable a => Int -> a -> Int
    hashWithSalt Int
    salt ([a] -> Int) -> (Vector a -> [a]) -> Vector a -> Int
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Vector a -> [a]
    forall a. Storable a => Vector a -> [a]
    Storable.toList
      {-# INLINE hashWithSalt #-}

    instance (Primitive.Prim a, Hashable a) => Hashable (Primitive.Vector a) where
      hashWithSalt :: Int -> Vector a -> Int
    hashWithSalt Int
    salt = Int -> [a] -> Int
    forall a. Hashable a => Int -> a -> Int
    hashWithSalt Int
    salt ([a] -> Int) -> (Vector a -> [a]) -> Vector a -> Int
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Vector a -> [a]
    forall a. Prim a => Vector a -> [a]
    Primitive.toList
      {-# INLINE hashWithSalt #-}

    instance Hashable1 Vector where
      liftHashWithSalt :: forall a. (Int -> a -> Int) -> Int -> Vector a -> Int
    liftHashWithSalt Int -> a -> Int
    itemHashWithSalt Int
    salt = (Int -> a -> Int) -> Int -> [a] -> Int
    forall a. (Int -> a -> Int) -> Int -> [a] -> Int
    forall (t :: * -> *) a.
    Hashable1 t =>
    (Int -> a -> Int) -> Int -> t a -> Int
    liftHashWithSalt Int -> a -> Int
    itemHashWithSalt Int
    salt ([a] -> Int) -> (Vector a -> [a]) -> Vector a -> Int
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Vector a -> [a]
    forall a. Vector a -> [a]
    Vector.toList
      {-# INLINE liftHashWithSalt #-}
    #endif