{-# 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
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 = 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 = 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 = 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 = forall a. Vector a -> Int -> a
(Vector.!)
  {-# INLINE index #-}

instance Lookup Vector where
  lookup :: forall a. Key Vector -> Vector a -> Maybe a
lookup = forall a b c. (a -> b -> c) -> b -> a -> c
flip 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 forall a. Vector a -> Int -> Maybe a
!? Key Vector
n of
    Just a
a ->  Vector a
v forall a. Vector a -> [(Int, a)] -> Vector a
// [(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 forall a. Vector a -> [(Int, a)] -> Vector a
// [(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 = 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 = 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 =
    forall (v :: * -> *) a. Vector v a => Bundle v a -> v a
G.unstream forall a b. (a -> b) -> a -> 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 = forall a. Vector a -> Int
Vector.length Vector (a -> b)
fs forall a. Num a => a -> a -> a
* forall a. Vector a -> Int
Vector.length Vector a
as
      results :: Bundle Vector b
results = forall a (v :: * -> *) b.
(a -> Bundle v b) -> Bundle v a -> Bundle v b
Stream.concatMap (a -> b) -> Bundle Vector b
body forall a b. (a -> b) -> 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 = forall a b (v :: * -> *). (a -> b) -> Bundle v a -> Bundle v b
Stream.map a -> b
f forall a b. (a -> b) -> a -> b
$ 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 = 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 = 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
(<!>) = forall a. Vector a -> Vector a -> Vector a
(++)
  {-# INLINE (<!>) #-}

instance Plus Vector where
  zero :: forall a. Vector a
zero = 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
     = forall a. Int -> [a] -> Vector a
Vector.fromListN (forall a. Vector a -> Int
Vector.length Vector a
v) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) (f :: * -> *) a b.
(TraversableWithKey t, Applicative f) =>
(Key t -> a -> f b) -> t a -> f (t b)
traverseWithKey Key Vector -> a -> f b
f (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 = forall a. Int -> (Int -> a) -> Vector a
generate (forall a. Vector a -> Int
length Vector a
v) (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 = forall a. Int -> (Int -> a) -> Vector a
generate (forall a. Vector a -> Int
length Vector a
v) (\Int
n -> Vector a -> b
f (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 = forall a. Hashable a => Int -> a -> Int
hashWithSalt Int
salt forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Vector a -> [a]
Vector.toList
  {-# INLINE hashWithSalt #-}

instance (Unboxed.Unbox a, Hashable a) => Hashable (Unboxed.Vector a) where
  hashWithSalt :: Int -> Vector a -> Int
hashWithSalt Int
salt = forall a. Hashable a => Int -> a -> Int
hashWithSalt Int
salt forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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 = forall a. Hashable a => Int -> a -> Int
hashWithSalt Int
salt forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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 = forall a. Hashable a => Int -> a -> Int
hashWithSalt Int
salt forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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 = forall (t :: * -> *) a.
Hashable1 t =>
(Int -> a -> Int) -> Int -> t a -> Int
liftHashWithSalt Int -> a -> Int
itemHashWithSalt Int
salt forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Vector a -> [a]
Vector.toList
  {-# INLINE liftHashWithSalt #-}
#endif