{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE Strict #-}
{-# LANGUAGE CPP #-}
module Data.Container.Vector (module Data.Container.Vector, module X) where
import qualified Prelude as P
import qualified Data.Text as UTF16
import Prologue hiding (Text, length, splitHead, concat, take, drop, index)
import Control.Monad.ST (runST)
import Data.Binary (Binary)
import Data.Vector.Binary ()
import qualified Data.Vector.Unboxed as Unboxed
import qualified GHC.Exts as Exts
import GHC.Exts (IsList)
import Data.Vector.Generic hiding (convert)
import Data.Vector.Generic as X (
length, null,
singleton, cons, snoc, concat,
unsafeIndex, unsafeHead, unsafeLast, unsafeTail, unsafeInit,
unsafeSlice, unsafeInit, unsafeTail, unsafeTake, unsafeDrop, splitAt,
span,
map, imap, concatMap
)
import qualified Data.Vector.Generic as V
import qualified Data.Vector.Generic.Mutable as M
alloc :: Vector v a => Int -> v a
alloc i = runST $ unsafeFreeze =<< M.new i ; {-# INLINE alloc #-}
replicate' :: Vector v a => Int -> v a -> v a
replicate' i = concat . P.replicate i ; {-# INLINE replicate' #-}
index, (!) :: Vector v a => v a -> Int -> Maybe a
index = (V.!?) ; {-# INLINE index #-}
(!) = index ; {-# INLINE (!) #-}
infixl 9 !
(!!) :: Vector v a => v a -> Int -> a
(!!) = unsafeIndex ; {-# INLINE (!!) #-}
infixl 9 !!
head, last :: Vector v a => v a -> Maybe a
head = fmap2 fst splitHead ; {-# INLINE head #-}
last = fmap2 fst splitLast ; {-# INLINE last #-}
init, tail :: Vector v a => v a -> Maybe (v a)
init = fmap2 snd splitLast ; {-# INLINE init #-}
tail = fmap2 snd splitHead ; {-# INLINE tail #-}
splitHead, splitLast :: Vector v a => v a -> Maybe (a, v a)
splitHead t = justIf (length t > 0) $ unsafeSplitHead t ; {-# INLINE splitHead #-}
splitLast t = justIf (length t > 0) $ unsafeSplitLast t ; {-# INLINE splitLast #-}
unsafeSplitHead, unsafeSplitLast :: Vector v a => v a -> (a, v a)
unsafeSplitHead t = (V.unsafeHead t, V.unsafeTail t) ; {-# INLINE unsafeSplitHead #-}
unsafeSplitLast t = (V.unsafeLast t, V.unsafeInit t) ; {-# INLINE unsafeSplitLast #-}
takeTill :: Vector v a => (a -> Bool) -> v a -> v a
takeTill f = \v -> maybe v (flip V.unsafeTake v) $ findIndex f v ; {-# INLINE takeTill #-}
takeWhile :: Vector v a => (a -> Bool) -> v a -> v a
takeWhile = takeTill . fmap not ; {-# INLINE takeWhile #-}
takeWhileStream :: Vector v a => (a -> Bool) -> v a -> v a
takeWhileStream = V.takeWhile ; {-# INLINE takeWhileStream #-}
dropWhileStream :: Vector v a => (a -> Bool) -> v a -> v a
dropWhileStream = V.dropWhile ; {-# INLINE dropWhileStream #-}
breakAll :: Vector v a => (a -> Bool) -> v a -> [v a]
breakAll f = go where
go v = case findIndex f v of
Nothing -> [v]
Just i -> unsafeTake i v : go (unsafeDrop (i+1) v)
{-# INLINE breakAll #-}
replaceUsing :: Vector v a => (a -> Bool) -> (a -> v a) -> v a -> v a
replaceUsing f rf = concat . go where
go v = case findIndex f v of
Nothing -> [v]
Just i -> unsafeTake i v : rf (unsafeIndex v i) : go (unsafeDrop (i+1) v)
{-# INLINE replaceUsing #-}
replace :: (Vector v a, Eq a) => a -> v a -> v a -> v a
replace a v = replaceUsing (a ==) (const v) ; {-# INLINE replace #-}
commonPrefixes :: (Vector v a, Eq a) => v a -> v a -> Maybe (v a, v a, v a)
commonPrefixes v v' = go 0 where
minlen = min (length v) (length v')
go i | i < minlen && a == b = go (i+1)
| i > 0 = Just (unsafeTake i v, unsafeDrop i v, unsafeDrop i v')
| otherwise = Nothing
where a = unsafeIndex v i
b = unsafeIndex v' i
#if MIN_VERSION_vector(0,12,0)
#else
instance Unboxed.Unbox a => Semigroup (Unboxed.Vector a) where (<>) = P.mappend
#endif
instance (Vector Unboxed.Vector a, Convertible' Char a) => IsString (Unboxed.Vector a) where fromString = convert ; {-# INLINE fromString #-}
instance (Vector Unboxed.Vector a, Convertible' Char a) => Convertible Char (Unboxed.Vector a) where convert = singleton . convert' ; {-# INLINE convert #-}
instance {-# OVERLAPPABLE #-} (Vector Unboxed.Vector a, Convertible' t a) => Convertible [t] (Unboxed.Vector a) where convert = V.fromList . fmap convert' ; {-# INLINE convert #-}
instance (Vector Unboxed.Vector a) => Convertible [a] (Unboxed.Vector a) where convert = V.fromList ; {-# INLINE convert #-}
instance {-# OVERLAPPABLE #-} (Vector Unboxed.Vector a, Convertible' a t) => Convertible (Unboxed.Vector a) [t] where convert = fmap convert' . V.toList ; {-# INLINE convert #-}
instance (Vector Unboxed.Vector a) => Convertible (Unboxed.Vector a) [a] where convert = V.toList ; {-# INLINE convert #-}
instance (Vector Unboxed.Vector a, Convertible' Char a) => Convertible UTF16.Text (Unboxed.Vector a) where convert = convertVia @[Char] ; {-# INLINE convert #-}
instance (Vector Unboxed.Vector a, Convertible' a Char) => Convertible (Unboxed.Vector a) UTF16.Text where convert = convertVia @[Char] ; {-# INLINE convert #-}