{- |
Chunky signal stream built on StorableVector.

Hints for fusion:
 - Higher order functions should always be inlined in the end
   in order to turn them into machine loops
   instead of calling a function in an inner loop.
-}
module Data.StorableVector.Lazy (
   -- constructors should not be exported
   Vector(SV, chunks),
   ChunkSize(ChunkSize),
   chunkSize,
   defaultChunkSize,
   empty,
   singleton,
   fromChunks,
   pack,
   unpack,
   packWith,
   unpackWith,
   unfoldr,
   unfoldrResult,
   sample,
   sampleN,
   iterate,
   repeat,
   cycle,
   replicate,
   null,
   length,
   equal,
   index,
   cons,
   append,
   extendL,
   concat,
   sliceVertical,
   snoc,
   map,
   reverse,
   foldl,
   foldl',
   foldr,
   foldMap,
   monoidConcatMap,
   any,
   all,
   maximum,
   minimum,
   pointer,
   viewL,
   viewR,
   switchL,
   switchR,
   scanl,
   mapAccumL,
   mapAccumR,
   crochetL,
   take,
   takeEnd,
   drop,
   splitAt,
   dropMarginRem,
   dropMargin,
   dropWhile,
   takeWhile,
   span,
   filter,
   zipWith,
   zipWith3,
   zipWith4,
   zipWithAppend,
   zipWithLastPattern,
   zipWithLastPattern3,
   zipWithLastPattern4,
   zipWithSize,
   zipWithSize3,
   zipWithSize4,
   sieve,
   deinterleave,
   interleaveFirstPattern,
   pad,
   compact,
   fromChunk,
   hGetContentsAsync,
   hGetContentsSync,
   hPut,
   readFileAsync,
   writeFile,
   appendFile,
   interact,
   -- should not be exported or should be exported from plain StorableVector
   crochetLChunk,
   -- should not be exported
   padAlt,
   cancelNullVector,
   moduleError,
   ) where

import qualified Data.List as List
import qualified Data.StorableVector as V
import qualified Data.StorableVector.Base as VB
import qualified Data.StorableVector.Lazy.PointerPrivate as Ptr

import qualified Numeric.NonNegative.Class as NonNeg

import qualified Data.List.HT as ListHT
import Data.Tuple.HT (mapPair, mapFst, mapSnd, swap, )
import Data.Maybe.HT (toMaybe, )
import Data.Maybe (fromMaybe, )

import Foreign.Storable (Storable)

import Data.Monoid (Monoid, mempty, mappend, mconcat, )
import Data.Semigroup (Semigroup, (<>), )
-- import Control.Arrow ((***))
import Control.Monad (liftM, liftM2, liftM3, liftM4, mfilter, )


import qualified System.IO as IO
import System.IO (openBinaryFile, IOMode(WriteMode, ReadMode, AppendMode),
                  hClose, Handle)

import Control.DeepSeq (NFData, rnf)
import Control.Exception (bracket, catch, )

import qualified System.IO.Error as Exc
import qualified System.Unsafe as Unsafe

import qualified Test.QuickCheck as QC


{-
import Prelude hiding
   (length, (++), concat, iterate, foldl, map, repeat, replicate, null,
    zip, zipWith, zipWith3, drop, take, splitAt, takeWhile, dropWhile, reverse)
-}

import qualified Prelude as P

import Data.Either (Either(Left, Right), either, )
import Data.Maybe (Maybe(Just, Nothing), maybe, )
import Data.Function (const, flip, id, ($), (.), )
import Data.Tuple (fst, snd, uncurry, )
import Data.Bool (Bool(True,False), not, (&&), )
import Data.Ord (Ord, (<), (>), (<=), (>=), min, max, )
import Data.Eq (Eq, (==), )
import Control.Monad (mapM_, fmap, (=<<), (>>=), (>>), return, )
import Text.Show (Show, showsPrec, showParen, showString, show, )
import Prelude
   (IO, error, IOError,
    FilePath, String, succ,
    Num, Int, sum, (+), (-), divMod, mod, fromInteger, )



newtype Vector a = SV {forall a. Vector a -> [Vector a]
chunks :: [V.Vector a]}


instance (Storable a) => Semigroup (Vector a) where
    <> :: Vector a -> Vector a -> Vector a
(<>) = forall a. Storable a => Vector a -> Vector a -> Vector a
append

instance (Storable a) => Monoid (Vector a) where
    mempty :: Vector a
mempty  = forall a. Storable a => Vector a
empty
    mappend :: Vector a -> Vector a -> Vector a
mappend = forall a. Storable a => Vector a -> Vector a -> Vector a
append
    mconcat :: [Vector a] -> Vector a
mconcat = forall a. Storable a => [Vector a] -> Vector a
concat

instance (Storable a, Eq a) => Eq (Vector a) where
   == :: Vector a -> Vector a -> Bool
(==) = forall a. (Storable a, Eq a) => Vector a -> Vector a -> Bool
equal

instance (Storable a, Show a) => Show (Vector a) where
   showsPrec :: Int -> Vector a -> ShowS
showsPrec Int
p Vector a
xs =
      Bool -> ShowS -> ShowS
showParen (Int
pforall a. Ord a => a -> a -> Bool
>=Int
10)
         (String -> ShowS
showString String
"VectorLazy.fromChunks " forall b c a. (b -> c) -> (a -> b) -> a -> c
.
          forall a. Show a => Int -> a -> ShowS
showsPrec Int
10 (forall a. Vector a -> [Vector a]
chunks Vector a
xs))

instance (Storable a, QC.Arbitrary a) => QC.Arbitrary (Vector a) where
   arbitrary :: Gen (Vector a)
arbitrary = forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 forall a. Storable a => ChunkSize -> [a] -> Vector a
pack forall a. Arbitrary a => Gen a
QC.arbitrary forall a. Arbitrary a => Gen a
QC.arbitrary

instance (Storable a) => NFData (Vector a) where
   rnf :: Vector a -> ()
rnf = forall a. NFData a => a -> ()
rnf forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
List.map forall a. NFData a => a -> ()
rnf forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Vector a -> [Vector a]
chunks


-- for a list of chunk sizes see "Data.StorableVector.LazySize".
newtype ChunkSize = ChunkSize Int
   deriving (ChunkSize -> ChunkSize -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ChunkSize -> ChunkSize -> Bool
$c/= :: ChunkSize -> ChunkSize -> Bool
== :: ChunkSize -> ChunkSize -> Bool
$c== :: ChunkSize -> ChunkSize -> Bool
Eq, Eq ChunkSize
ChunkSize -> ChunkSize -> Bool
ChunkSize -> ChunkSize -> Ordering
ChunkSize -> ChunkSize -> ChunkSize
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: ChunkSize -> ChunkSize -> ChunkSize
$cmin :: ChunkSize -> ChunkSize -> ChunkSize
max :: ChunkSize -> ChunkSize -> ChunkSize
$cmax :: ChunkSize -> ChunkSize -> ChunkSize
>= :: ChunkSize -> ChunkSize -> Bool
$c>= :: ChunkSize -> ChunkSize -> Bool
> :: ChunkSize -> ChunkSize -> Bool
$c> :: ChunkSize -> ChunkSize -> Bool
<= :: ChunkSize -> ChunkSize -> Bool
$c<= :: ChunkSize -> ChunkSize -> Bool
< :: ChunkSize -> ChunkSize -> Bool
$c< :: ChunkSize -> ChunkSize -> Bool
compare :: ChunkSize -> ChunkSize -> Ordering
$ccompare :: ChunkSize -> ChunkSize -> Ordering
Ord, Int -> ChunkSize -> ShowS
[ChunkSize] -> ShowS
ChunkSize -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ChunkSize] -> ShowS
$cshowList :: [ChunkSize] -> ShowS
show :: ChunkSize -> String
$cshow :: ChunkSize -> String
showsPrec :: Int -> ChunkSize -> ShowS
$cshowsPrec :: Int -> ChunkSize -> ShowS
Show)

instance QC.Arbitrary ChunkSize where
   arbitrary :: Gen ChunkSize
arbitrary = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Int -> ChunkSize
ChunkSize forall a b. (a -> b) -> a -> b
$ forall a. Random a => (a, a) -> Gen a
QC.choose (Int
1,Int
2048)

{-
ToDo:
Since non-negative-0.1 we have the Monoid superclass for NonNeg.
Maybe we do not need the Num instance anymore.
-}
instance Num ChunkSize where
   (ChunkSize Int
x) + :: ChunkSize -> ChunkSize -> ChunkSize
+ (ChunkSize Int
y)  =  Int -> ChunkSize
ChunkSize (Int
xforall a. Num a => a -> a -> a
+Int
y)
   (-)  =  forall a. String -> String -> a
moduleError String
"ChunkSize.-" String
"intentionally unimplemented"
   * :: ChunkSize -> ChunkSize -> ChunkSize
(*)  =  forall a. String -> String -> a
moduleError String
"ChunkSize.*" String
"intentionally unimplemented"
   abs :: ChunkSize -> ChunkSize
abs  =  forall a. String -> String -> a
moduleError String
"ChunkSize.abs" String
"intentionally unimplemented"
   signum :: ChunkSize -> ChunkSize
signum  =  forall a. String -> String -> a
moduleError String
"ChunkSize.signum" String
"intentionally unimplemented"
   fromInteger :: Integer -> ChunkSize
fromInteger = Int -> ChunkSize
ChunkSize forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Num a => Integer -> a
fromInteger

instance Semigroup ChunkSize where
   ChunkSize Int
x <> :: ChunkSize -> ChunkSize -> ChunkSize
<> ChunkSize Int
y = Int -> ChunkSize
ChunkSize (Int
xforall a. Num a => a -> a -> a
+Int
y)

instance Monoid ChunkSize where
   mempty :: ChunkSize
mempty = Int -> ChunkSize
ChunkSize Int
0
   mappend :: ChunkSize -> ChunkSize -> ChunkSize
mappend (ChunkSize Int
x) (ChunkSize Int
y) = Int -> ChunkSize
ChunkSize (Int
xforall a. Num a => a -> a -> a
+Int
y)
   mconcat :: [ChunkSize] -> ChunkSize
mconcat = Int -> ChunkSize
ChunkSize forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
List.map (\(ChunkSize Int
c) -> Int
c)

instance NonNeg.C ChunkSize where
   split :: ChunkSize -> ChunkSize -> (ChunkSize, (Bool, ChunkSize))
split = forall b a.
(Ord b, Num b) =>
(a -> b) -> (b -> a) -> a -> a -> (a, (Bool, a))
NonNeg.splitDefault (\(ChunkSize Int
c) -> Int
c) Int -> ChunkSize
ChunkSize

chunkSize :: Int -> ChunkSize
chunkSize :: Int -> ChunkSize
chunkSize Int
x =
   Int -> ChunkSize
ChunkSize forall a b. (a -> b) -> a -> b
$
      if Int
xforall a. Ord a => a -> a -> Bool
>Int
0
        then Int
x
        else forall a. String -> String -> a
moduleError String
"chunkSize" (String
"no positive number: " forall a. [a] -> [a] -> [a]
List.++ forall a. Show a => a -> String
show Int
x)

defaultChunkSize :: ChunkSize
defaultChunkSize :: ChunkSize
defaultChunkSize =
   Int -> ChunkSize
ChunkSize Int
1024



-- * Introducing and eliminating 'Vector's

{-# INLINE empty #-}
empty :: (Storable a) => Vector a
empty :: forall a. Storable a => Vector a
empty = forall a. [Vector a] -> Vector a
SV []

{-# INLINE singleton #-}
singleton :: (Storable a) => a -> Vector a
singleton :: forall a. Storable a => a -> Vector a
singleton a
x = forall a. [Vector a] -> Vector a
SV [forall a. Storable a => a -> Vector a
V.singleton a
x]

fromChunks :: (Storable a) => [V.Vector a] -> Vector a
fromChunks :: forall a. Storable a => [Vector a] -> Vector a
fromChunks = forall a. [Vector a] -> Vector a
SV

pack :: (Storable a) => ChunkSize -> [a] -> Vector a
pack :: forall a. Storable a => ChunkSize -> [a] -> Vector a
pack ChunkSize
size = forall b a.
Storable b =>
ChunkSize -> (a -> Maybe (b, a)) -> a -> Vector b
unfoldr ChunkSize
size forall a. [a] -> Maybe (a, [a])
ListHT.viewL

unpack :: (Storable a) => Vector a -> [a]
unpack :: forall a. Storable a => Vector a -> [a]
unpack = forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
List.concatMap forall a. Storable a => Vector a -> [a]
V.unpack forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Vector a -> [Vector a]
chunks


{-# WARNING packWith "It seems to be used nowhere and might be removed." #-}
{-# INLINE packWith #-}
packWith :: (Storable b) => ChunkSize -> (a -> b) -> [a] -> Vector b
packWith :: forall b a. Storable b => ChunkSize -> (a -> b) -> [a] -> Vector b
packWith ChunkSize
size a -> b
f = forall b a.
Storable b =>
ChunkSize -> (a -> Maybe (b, a)) -> a -> Vector b
unfoldr ChunkSize
size (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall a c b. (a -> c) -> (a, b) -> (c, b)
mapFst a -> b
f) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [a] -> Maybe (a, [a])
ListHT.viewL)

{-# WARNING unpackWith "It seems to be used nowhere and might be removed." #-}
{-# INLINE unpackWith #-}
unpackWith :: (Storable a) => (a -> b) -> Vector a -> [b]
unpackWith :: forall a b. Storable a => (a -> b) -> Vector a -> [b]
unpackWith a -> b
f = forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
List.concatMap (forall a b. Storable a => (a -> b) -> Vector a -> [b]
V.unpackWith a -> b
f) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Vector a -> [Vector a]
chunks


{-# INLINE unfoldr #-}
unfoldr :: (Storable b) =>
   ChunkSize ->
   (a -> Maybe (b,a)) ->
   a ->
   Vector b
unfoldr :: forall b a.
Storable b =>
ChunkSize -> (a -> Maybe (b, a)) -> a -> Vector b
unfoldr (ChunkSize Int
size) a -> Maybe (b, a)
f =
   forall a. [Vector a] -> Vector a
SV forall b c a. (b -> c) -> (a -> b) -> a -> c
.
   forall b a. (b -> Maybe (a, b)) -> b -> [a]
List.unfoldr (forall a b. (Vector a, b) -> Maybe (Vector a, b)
cancelNullVector forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall b a.
Storable b =>
Int -> (a -> Maybe (b, a)) -> a -> (Vector b, Maybe a)
V.unfoldrN Int
size a -> Maybe (b, a)
f forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<) forall b c a. (b -> c) -> (a -> b) -> a -> c
.
   forall a. a -> Maybe a
Just

{- |
Example:

> *Data.StorableVector.Lazy> unfoldrResult (ChunkSize 5) (\c -> if c>'z' then Left (Char.ord c) else Right (c, succ c)) 'a'
> (VectorLazy.fromChunks [Vector.pack "abcde",Vector.pack "fghij",Vector.pack "klmno",Vector.pack "pqrst",Vector.pack "uvwxy",Vector.pack "z"],123)
-}
{-# INLINE unfoldrResult #-}
unfoldrResult :: (Storable b) =>
   ChunkSize ->
   (a -> Either c (b, a)) ->
   a ->
   (Vector b, c)
unfoldrResult :: forall b a c.
Storable b =>
ChunkSize -> (a -> Either c (b, a)) -> a -> (Vector b, c)
unfoldrResult (ChunkSize Int
size) a -> Either c (b, a)
f =
   let recourse :: a -> ([Vector b], c)
recourse a
a0 =
          let (Vector b
chunk, Either c a
a1) =
                 forall b a c.
Storable b =>
Int -> (a -> c) -> (a -> Either c (b, a)) -> a -> (Vector b, c)
V.unfoldrResultN Int
size forall a b. b -> Either a b
Right (forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (forall a b. a -> Either a b
Left forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. a -> Either a b
Left) forall a b. b -> Either a b
Right forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Either c (b, a)
f) a
a0
          in  forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either
                 ((,) (if forall a. Vector a -> Bool
V.null Vector b
chunk then [] else [Vector b
chunk]))
                 (forall a c b. (a -> c) -> (a, b) -> (c, b)
mapFst (Vector b
chunk forall a. a -> [a] -> [a]
:) forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> ([Vector b], c)
recourse) Either c a
a1
   in  forall a c b. (a -> c) -> (a, b) -> (c, b)
mapFst forall a. [Vector a] -> Vector a
SV forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> ([Vector b], c)
recourse


{-# INLINE sample #-}
sample :: (Storable a) => ChunkSize -> (Int -> a) -> Vector a
sample :: forall a. Storable a => ChunkSize -> (Int -> a) -> Vector a
sample ChunkSize
size Int -> a
f =
   forall b a.
Storable b =>
ChunkSize -> (a -> Maybe (b, a)) -> a -> Vector b
unfoldr ChunkSize
size (\Int
i -> forall a. a -> Maybe a
Just (Int -> a
f Int
i, forall a. Enum a => a -> a
succ Int
i)) Int
0

{-# INLINE sampleN #-}
sampleN :: (Storable a) => ChunkSize -> Int -> (Int -> a) -> Vector a
sampleN :: forall a. Storable a => ChunkSize -> Int -> (Int -> a) -> Vector a
sampleN ChunkSize
size Int
n Int -> a
f =
   forall b a.
Storable b =>
ChunkSize -> (a -> Maybe (b, a)) -> a -> Vector b
unfoldr ChunkSize
size (\Int
i -> forall a. Bool -> a -> Maybe a
toMaybe (Int
iforall a. Ord a => a -> a -> Bool
<Int
n) (Int -> a
f Int
i, forall a. Enum a => a -> a
succ Int
i)) Int
0


{-# INLINE iterate #-}
iterate :: Storable a => ChunkSize -> (a -> a) -> a -> Vector a
iterate :: forall a. Storable a => ChunkSize -> (a -> a) -> a -> Vector a
iterate ChunkSize
size a -> a
f = forall b a.
Storable b =>
ChunkSize -> (a -> Maybe (b, a)) -> a -> Vector b
unfoldr ChunkSize
size (\a
x -> forall a. a -> Maybe a
Just (a
x, a -> a
f a
x))

repeat :: Storable a => ChunkSize -> a -> Vector a
repeat :: forall a. Storable a => ChunkSize -> a -> Vector a
repeat (ChunkSize Int
size) =
   forall a. [Vector a] -> Vector a
SV forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> [a]
List.repeat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Storable a => Int -> a -> Vector a
V.replicate Int
size

cycle :: Storable a => Vector a -> Vector a
cycle :: forall a. Storable a => Vector a -> Vector a
cycle =
   forall a. [Vector a] -> Vector a
SV forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [a] -> [a]
List.cycle forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Vector a -> [Vector a]
chunks

replicate :: Storable a => ChunkSize -> Int -> a -> Vector a
replicate :: forall a. Storable a => ChunkSize -> Int -> a -> Vector a
replicate (ChunkSize Int
size) Int
n a
x =
   let (Int
numChunks, Int
rest) = forall a. Integral a => a -> a -> (a, a)
divMod Int
n Int
size
   in  forall a. Storable a => Vector a -> Vector a -> Vector a
append
          (forall a. [Vector a] -> Vector a
SV (forall a. Int -> a -> [a]
List.replicate Int
numChunks (forall a. Storable a => Int -> a -> Vector a
V.replicate Int
size a
x)))
          (forall a. Storable a => Vector a -> Vector a
fromChunk (forall a. Storable a => Int -> a -> Vector a
V.replicate Int
rest a
x))




-- * Basic interface

{-# INLINE null #-}
null :: (Storable a) => Vector a -> Bool
null :: forall a. Storable a => Vector a -> Bool
null = forall (t :: * -> *) a. Foldable t => t a -> Bool
List.null forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Vector a -> [Vector a]
chunks

length :: Vector a -> Int
length :: forall a. Vector a -> Int
length = forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
List.map forall a. Vector a -> Int
V.length forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Vector a -> [Vector a]
chunks

equal :: (Storable a, Eq a) => Vector a -> Vector a -> Bool
equal :: forall a. (Storable a, Eq a) => Vector a -> Vector a -> Bool
equal (SV [Vector a]
xs0) (SV [Vector a]
ys0) =
   let recourse :: [Vector a] -> [Vector a] -> Bool
recourse (Vector a
x:[Vector a]
xs) (Vector a
y:[Vector a]
ys) =
          let l :: Int
l = forall a. Ord a => a -> a -> a
min (forall a. Vector a -> Int
V.length Vector a
x) (forall a. Vector a -> Int
V.length Vector a
y)
              (Vector a
xPrefix, Vector a
xSuffix) = forall a. Storable a => Int -> Vector a -> (Vector a, Vector a)
V.splitAt Int
l Vector a
x
              (Vector a
yPrefix, Vector a
ySuffix) = forall a. Storable a => Int -> Vector a -> (Vector a, Vector a)
V.splitAt Int
l Vector a
y
              build :: Vector a -> [Vector a] -> [Vector a]
build Vector a
z [Vector a]
zs =
                 if forall a. Vector a -> Bool
V.null Vector a
z then [Vector a]
zs else Vector a
zforall a. a -> [a] -> [a]
:[Vector a]
zs
          in  Vector a
xPrefix forall a. Eq a => a -> a -> Bool
== Vector a
yPrefix Bool -> Bool -> Bool
&&
              [Vector a] -> [Vector a] -> Bool
recourse (forall {a}. Vector a -> [Vector a] -> [Vector a]
build Vector a
xSuffix [Vector a]
xs) (forall {a}. Vector a -> [Vector a] -> [Vector a]
build Vector a
ySuffix [Vector a]
ys)
       recourse [] [] = Bool
True
       -- this requires that chunks will always be non-empty
       recourse [Vector a]
_ [Vector a]
_ = Bool
False
   in  forall {a}. (Eq a, Storable a) => [Vector a] -> [Vector a] -> Bool
recourse [Vector a]
xs0 [Vector a]
ys0

index :: (Storable a) => Vector a -> Int -> a
index :: forall a. Storable a => Vector a -> Int -> a
index (SV [Vector a]
xs) Int
n =
   if Int
n forall a. Ord a => a -> a -> Bool
< Int
0
     then
        forall a. String -> String -> a
moduleError String
"index"
           (String
"negative index: " forall a. [a] -> [a] -> [a]
List.++ forall a. Show a => a -> String
show Int
n)
     else
        forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
List.foldr
           (\Vector a
x Int -> a
k Int
m0 ->
              let m1 :: Int
m1 = Int
m0 forall a. Num a => a -> a -> a
- forall a. Vector a -> Int
V.length Vector a
x
              in  if Int
m1 forall a. Ord a => a -> a -> Bool
< Int
0
                    then forall a. Storable a => Vector a -> Int -> a
VB.unsafeIndex Vector a
x Int
m0
                    else Int -> a
k Int
m1)
           (\Int
m -> forall a. String -> String -> a
moduleError String
"index"
                     (String
"index too large: " forall a. [a] -> [a] -> [a]
List.++ forall a. Show a => a -> String
show Int
n
                      forall a. [a] -> [a] -> [a]
List.++ String
", length = " forall a. [a] -> [a] -> [a]
List.++ forall a. Show a => a -> String
show (Int
nforall a. Num a => a -> a -> a
-Int
m)))
           [Vector a]
xs Int
n


{-# NOINLINE [0] cons #-}
cons :: Storable a => a -> Vector a -> Vector a
cons :: forall a. Storable a => a -> Vector a -> Vector a
cons a
x = forall a. [Vector a] -> Vector a
SV forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a. Storable a => a -> Vector a
V.singleton a
x forall a. a -> [a] -> [a]
:) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Vector a -> [Vector a]
chunks

infixr 5 `append`

{-# NOINLINE [0] append #-}
append :: Storable a => Vector a -> Vector a -> Vector a
append :: forall a. Storable a => Vector a -> Vector a -> Vector a
append (SV [Vector a]
xs) (SV [Vector a]
ys)  =  forall a. [Vector a] -> Vector a
SV ([Vector a]
xs forall a. [a] -> [a] -> [a]
List.++ [Vector a]
ys)


{- |
@extendL size x y@
prepends the chunk @x@ and merges it with the first chunk of @y@
if the total size is at most @size@.
This way you can prepend small chunks
while asserting a reasonable average size for chunks.
-}
extendL :: Storable a => ChunkSize -> V.Vector a -> Vector a -> Vector a
extendL :: forall a.
Storable a =>
ChunkSize -> Vector a -> Vector a -> Vector a
extendL (ChunkSize Int
size) Vector a
x (SV [Vector a]
yt) =
   forall a. [Vector a] -> Vector a
SV forall a b. (a -> b) -> a -> b
$
   forall b a. b -> (a -> b) -> Maybe a -> b
maybe
      [Vector a
x]
      (\(Vector a
y,[Vector a]
ys) ->
          if forall a. Vector a -> Int
V.length Vector a
x forall a. Num a => a -> a -> a
+ forall a. Vector a -> Int
V.length Vector a
y forall a. Ord a => a -> a -> Bool
<= Int
size
            then forall a. Storable a => Vector a -> Vector a -> Vector a
V.append Vector a
x Vector a
y forall a. a -> [a] -> [a]
: [Vector a]
ys
            else Vector a
xforall a. a -> [a] -> [a]
:[Vector a]
yt)
      (forall a. [a] -> Maybe (a, [a])
ListHT.viewL [Vector a]
yt)


concat :: (Storable a) => [Vector a] -> Vector a
concat :: forall a. Storable a => [Vector a] -> Vector a
concat = forall a. [Vector a] -> Vector a
SV forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) a. Foldable t => t [a] -> [a]
List.concat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
List.map forall a. Vector a -> [Vector a]
chunks

sliceVertical :: (Storable a) => Int -> Vector a -> [Vector a]
sliceVertical :: forall a. Storable a => Int -> Vector a -> [Vector a]
sliceVertical Int
n =
   forall b a. (b -> Maybe (a, b)) -> b -> [a]
List.unfoldr (\Vector a
x -> forall a. Bool -> a -> Maybe a
toMaybe (Bool -> Bool
not (forall a. Storable a => Vector a -> Bool
null Vector a
x)) (forall a. Storable a => Int -> Vector a -> (Vector a, Vector a)
splitAt Int
n Vector a
x))

{-# NOINLINE [0] snoc #-}
snoc :: Storable a => Vector a -> a -> Vector a
snoc :: forall a. Storable a => Vector a -> a -> Vector a
snoc Vector a
xs a
x = forall a. Storable a => Vector a -> Vector a -> Vector a
append Vector a
xs forall a b. (a -> b) -> a -> b
$ forall a. Storable a => a -> Vector a
singleton a
x


-- * Transformations

{-# INLINE map #-}
map :: (Storable x, Storable y) =>
      (x -> y)
   -> Vector x
   -> Vector y
map :: forall x y.
(Storable x, Storable y) =>
(x -> y) -> Vector x -> Vector y
map x -> y
f = forall a. [Vector a] -> Vector a
SV forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
List.map (forall a b.
(Storable a, Storable b) =>
(a -> b) -> Vector a -> Vector b
V.map x -> y
f) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Vector a -> [Vector a]
chunks


reverse :: Storable a => Vector a -> Vector a
reverse :: forall a. Storable a => Vector a -> Vector a
reverse =
   forall a. [Vector a] -> Vector a
SV forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [a] -> [a]
List.reverse forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
List.map forall a. Storable a => Vector a -> Vector a
V.reverse forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Vector a -> [Vector a]
chunks


-- * Reducing 'Vector's

{-# INLINE foldl #-}
foldl :: Storable b => (a -> b -> a) -> a -> Vector b -> a
foldl :: forall b a. Storable b => (a -> b -> a) -> a -> Vector b -> a
foldl a -> b -> a
f a
x0 = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
List.foldl (forall a b. Storable a => (b -> a -> b) -> b -> Vector a -> b
V.foldl a -> b -> a
f) a
x0 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Vector a -> [Vector a]
chunks

{-# INLINE foldl' #-}
foldl' :: Storable b => (a -> b -> a) -> a -> Vector b -> a
foldl' :: forall b a. Storable b => (a -> b -> a) -> a -> Vector b -> a
foldl' a -> b -> a
f a
x0 = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
List.foldl' (forall a b. Storable a => (b -> a -> b) -> b -> Vector a -> b
V.foldl a -> b -> a
f) a
x0 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Vector a -> [Vector a]
chunks

{-# INLINE foldr #-}
foldr :: Storable b => (b -> a -> a) -> a -> Vector b -> a
foldr :: forall b a. Storable b => (b -> a -> a) -> a -> Vector b -> a
foldr b -> a -> a
f a
x0 = forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
List.foldr (forall a b c. (a -> b -> c) -> b -> a -> c
flip (forall a b. Storable a => (a -> b -> b) -> b -> Vector a -> b
V.foldr b -> a -> a
f)) a
x0 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Vector a -> [Vector a]
chunks


{-# INLINE foldMap #-}
foldMap :: (Storable a, Monoid m) => (a -> m) -> Vector a -> m
foldMap :: forall a m. (Storable a, Monoid m) => (a -> m) -> Vector a -> m
foldMap a -> m
f = forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
List.foldr (forall a. Monoid a => a -> a -> a
mappend forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a m. (Storable a, Monoid m) => (a -> m) -> Vector a -> m
V.foldMap a -> m
f) forall a. Monoid a => a
mempty forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Vector a -> [Vector a]
chunks

{-# DEPRECATED monoidConcatMap "Use foldMap instead." #-}
{-# INLINE monoidConcatMap #-}
monoidConcatMap :: (Storable a, Monoid m) => (a -> m) -> Vector a -> m
monoidConcatMap :: forall a m. (Storable a, Monoid m) => (a -> m) -> Vector a -> m
monoidConcatMap = forall a m. (Storable a, Monoid m) => (a -> m) -> Vector a -> m
foldMap

{-# INLINE any #-}
any :: (Storable a) => (a -> Bool) -> Vector a -> Bool
any :: forall a. Storable a => (a -> Bool) -> Vector a -> Bool
any a -> Bool
p = forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
List.any (forall a. Storable a => (a -> Bool) -> Vector a -> Bool
V.any a -> Bool
p) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Vector a -> [Vector a]
chunks

{-# INLINE all #-}
all :: (Storable a) => (a -> Bool) -> Vector a -> Bool
all :: forall a. Storable a => (a -> Bool) -> Vector a -> Bool
all a -> Bool
p = forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
List.all (forall a. Storable a => (a -> Bool) -> Vector a -> Bool
V.all a -> Bool
p) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Vector a -> [Vector a]
chunks

maximum, _maximum :: (Storable a, Ord a) => Vector a -> a
maximum :: forall a. (Storable a, Ord a) => Vector a -> a
maximum = forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
List.maximum forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
List.map forall a. (Storable a, Ord a) => Vector a -> a
V.maximum forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Vector a -> [Vector a]
chunks
_maximum :: forall a. (Storable a, Ord a) => Vector a -> a
_maximum = forall a. (a -> a -> a) -> [a] -> a
List.foldl1' forall a. Ord a => a -> a -> a
max forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
List.map forall a. (Storable a, Ord a) => Vector a -> a
V.maximum forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Vector a -> [Vector a]
chunks

minimum, _minimum :: (Storable a, Ord a) => Vector a -> a
minimum :: forall a. (Storable a, Ord a) => Vector a -> a
minimum = forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
List.minimum forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
List.map forall a. (Storable a, Ord a) => Vector a -> a
V.minimum forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Vector a -> [Vector a]
chunks
_minimum :: forall a. (Storable a, Ord a) => Vector a -> a
_minimum = forall a. (a -> a -> a) -> [a] -> a
List.foldl1' forall a. Ord a => a -> a -> a
min forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
List.map forall a. (Storable a, Ord a) => Vector a -> a
V.minimum forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Vector a -> [Vector a]
chunks

{-
It is not clear whether this implementation is good.
Associativity depends on the chunk structure,
but in principle chunks could be summed in parallel.

sum :: (Storable a, Num a) => Vector a -> a
sum =
   List.sum . List.map V.sum . chunks

product :: (Storable a, Num a) => Vector a -> a
product =
   List.product . List.map V.product . chunks
-}


-- * inspecting a vector

{-# INLINE pointer #-}
pointer :: Storable a => Vector a -> Ptr.Pointer a
pointer :: forall a. Storable a => Vector a -> Pointer a
pointer = forall a. Storable a => [Vector a] -> Pointer a
Ptr.cons forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Vector a -> [Vector a]
chunks

{-# INLINE viewL #-}
viewL :: Storable a => Vector a -> Maybe (a, Vector a)
viewL :: forall a. Storable a => Vector a -> Maybe (a, Vector a)
viewL (SV [Vector a]
xs0) =
   do (Vector a
x,[Vector a]
xs) <- forall a. [a] -> Maybe (a, [a])
ListHT.viewL [Vector a]
xs0
      (a
y,Vector a
ys) <- forall a. Storable a => Vector a -> Maybe (a, Vector a)
V.viewL Vector a
x
      forall (m :: * -> *) a. Monad m => a -> m a
return (a
y, forall a. Storable a => Vector a -> Vector a -> Vector a
append (forall a. Storable a => Vector a -> Vector a
fromChunk Vector a
ys) (forall a. [Vector a] -> Vector a
SV [Vector a]
xs))

{-# INLINE viewR #-}
viewR :: Storable a => Vector a -> Maybe (Vector a, a)
viewR :: forall a. Storable a => Vector a -> Maybe (Vector a, a)
viewR (SV [Vector a]
xs0) =
   do ([Vector a], Vector a)
xsp <- forall a. [a] -> Maybe ([a], a)
ListHT.viewR [Vector a]
xs0
      let ([Vector a]
xs,Vector a
x) = ([Vector a], Vector a)
xsp
{-
   do ~(xs,x) <- ListHT.viewR xs0
-}
      let (Vector a
ys,a
y) = forall a. a -> Maybe a -> a
fromMaybe (forall a. String -> String -> a
moduleError String
"viewR" String
"last chunk empty") (forall a. Storable a => Vector a -> Maybe (Vector a, a)
V.viewR Vector a
x)
      forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. Storable a => Vector a -> Vector a -> Vector a
append (forall a. [Vector a] -> Vector a
SV [Vector a]
xs) (forall a. Storable a => Vector a -> Vector a
fromChunk Vector a
ys), a
y)

{-# INLINE switchL #-}
switchL :: Storable a => b -> (a -> Vector a -> b) -> Vector a -> b
switchL :: forall a b.
Storable a =>
b -> (a -> Vector a -> b) -> Vector a -> b
switchL b
n a -> Vector a -> b
j =
   forall b a. b -> (a -> b) -> Maybe a -> b
maybe b
n (forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry a -> Vector a -> b
j) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Storable a => Vector a -> Maybe (a, Vector a)
viewL

{-# INLINE switchR #-}
switchR :: Storable a => b -> (Vector a -> a -> b) -> Vector a -> b
switchR :: forall a b.
Storable a =>
b -> (Vector a -> a -> b) -> Vector a -> b
switchR b
n Vector a -> a -> b
j =
   forall b a. b -> (a -> b) -> Maybe a -> b
maybe b
n (forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Vector a -> a -> b
j) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Storable a => Vector a -> Maybe (Vector a, a)
viewR


{-
viewLSafe :: Storable a => Vector a -> Maybe (a, Vector a)
viewLSafe (SV xs0) =
   -- dropWhile would be unnecessary if we require that all chunks are non-empty
   do (x,xs) <- ListHT.viewL (List.dropWhile V.null xs0)
      (y,ys) <- viewLVector x
      return (y, append (fromChunk ys) (SV xs))

viewRSafe :: Storable a => Vector a -> Maybe (Vector a, a)
viewRSafe (SV xs0) =
   -- dropWhile would be unnecessary if we require that all chunks are non-empty
   do (xs,x) <- ListHT.viewR (dropWhileRev V.null xs0)
      (ys,y) <- V.viewR x
      return (append (SV xs) (fromChunk ys), y)
-}


{-# INLINE scanl #-}
scanl :: (Storable a, Storable b) =>
   (a -> b -> a) -> a -> Vector b -> Vector a
scanl :: forall a b.
(Storable a, Storable b) =>
(a -> b -> a) -> a -> Vector b -> Vector a
scanl a -> b -> a
f a
start =
   forall a. Storable a => a -> Vector a -> Vector a
cons a
start forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> b
snd forall b c a. (b -> c) -> (a -> b) -> a -> c
.
   forall a b acc.
(Storable a, Storable b) =>
(acc -> a -> (acc, b)) -> acc -> Vector a -> (acc, Vector b)
mapAccumL (\a
acc -> (\a
b -> (a
b,a
b)) forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b -> a
f a
acc) a
start

{-# INLINE mapAccumL #-}
mapAccumL :: (Storable a, Storable b) =>
   (acc -> a -> (acc, b)) -> acc -> Vector a -> (acc, Vector b)
mapAccumL :: forall a b acc.
(Storable a, Storable b) =>
(acc -> a -> (acc, b)) -> acc -> Vector a -> (acc, Vector b)
mapAccumL acc -> a -> (acc, b)
f acc
start =
   forall b c a. (b -> c) -> (a, b) -> (a, c)
mapSnd forall a. [Vector a] -> Vector a
SV forall b c a. (b -> c) -> (a -> b) -> a -> c
.
   forall (t :: * -> *) s a b.
Traversable t =>
(s -> a -> (s, b)) -> s -> t a -> (s, t b)
List.mapAccumL (forall a b acc.
(Storable a, Storable b) =>
(acc -> a -> (acc, b)) -> acc -> Vector a -> (acc, Vector b)
V.mapAccumL acc -> a -> (acc, b)
f) acc
start forall b c a. (b -> c) -> (a -> b) -> a -> c
.
   forall a. Vector a -> [Vector a]
chunks

{-# INLINE mapAccumR #-}
mapAccumR :: (Storable a, Storable b) =>
   (acc -> a -> (acc, b)) -> acc -> Vector a -> (acc, Vector b)
mapAccumR :: forall a b acc.
(Storable a, Storable b) =>
(acc -> a -> (acc, b)) -> acc -> Vector a -> (acc, Vector b)
mapAccumR acc -> a -> (acc, b)
f acc
start =
   forall b c a. (b -> c) -> (a, b) -> (a, c)
mapSnd forall a. [Vector a] -> Vector a
SV forall b c a. (b -> c) -> (a -> b) -> a -> c
.
   forall (t :: * -> *) s a b.
Traversable t =>
(s -> a -> (s, b)) -> s -> t a -> (s, t b)
List.mapAccumR (forall a b acc.
(Storable a, Storable b) =>
(acc -> a -> (acc, b)) -> acc -> Vector a -> (acc, Vector b)
V.mapAccumR acc -> a -> (acc, b)
f) acc
start forall b c a. (b -> c) -> (a -> b) -> a -> c
.
   forall a. Vector a -> [Vector a]
chunks

{-# DEPRECATED crochetLChunk "Use Storable.Vector.crochetLResult" #-}
{-# INLINE crochetLChunk #-}
crochetLChunk :: (Storable x, Storable y) =>
      (x -> acc -> Maybe (y, acc))
   -> acc
   -> V.Vector x
   -> (V.Vector y, Maybe acc)
crochetLChunk :: forall x y acc.
(Storable x, Storable y) =>
(x -> acc -> Maybe (y, acc))
-> acc -> Vector x -> (Vector y, Maybe acc)
crochetLChunk = forall x y acc.
(Storable x, Storable y) =>
(x -> acc -> Maybe (y, acc))
-> acc -> Vector x -> (Vector y, Maybe acc)
V.crochetLResult

{-# INLINE crochetL #-}
crochetL :: (Storable x, Storable y) =>
      (x -> acc -> Maybe (y, acc))
   -> acc
   -> Vector x
   -> Vector y
crochetL :: forall x y acc.
(Storable x, Storable y) =>
(x -> acc -> Maybe (y, acc)) -> acc -> Vector x -> Vector y
crochetL x -> acc -> Maybe (y, acc)
f acc
acc0 =
   forall a. [Vector a] -> Vector a
SV forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall b a. (b -> Maybe (a, b)) -> b -> [a]
List.unfoldr (\([Vector x]
xt,Maybe acc
acc) ->
       do (Vector x
x,[Vector x]
xs) <- forall a. [a] -> Maybe (a, [a])
ListHT.viewL [Vector x]
xt
          acc
acc' <- Maybe acc
acc
          forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall b c a. (b -> c) -> (a, b) -> (a, c)
mapSnd ((,) [Vector x]
xs) forall a b. (a -> b) -> a -> b
$ forall x y acc.
(Storable x, Storable y) =>
(x -> acc -> Maybe (y, acc))
-> acc -> Vector x -> (Vector y, Maybe acc)
V.crochetLResult x -> acc -> Maybe (y, acc)
f acc
acc' Vector x
x) forall b c a. (b -> c) -> (a -> b) -> a -> c
.
   forall a b c. (a -> b -> c) -> b -> a -> c
flip (,) (forall a. a -> Maybe a
Just acc
acc0) forall b c a. (b -> c) -> (a -> b) -> a -> c
.
   forall a. Vector a -> [Vector a]
chunks



-- * sub-vectors

{-# INLINE take #-}
take :: (Storable a) => Int -> Vector a -> Vector a
{- this order of pattern matches is certainly the most lazy one
> take 4 (pack (chunkSize 2) $ "abcd" List.++ undefined)
VectorLazy.fromChunks [Vector.pack "ab",Vector.pack "cd"]
-}
take :: forall a. Storable a => Int -> Vector a -> Vector a
take Int
0 Vector a
_ = forall a. Storable a => Vector a
empty
take Int
_ (SV []) = forall a. Storable a => Vector a
empty
take Int
n (SV (Vector a
x:[Vector a]
xs)) =
   let m :: Int
m = forall a. Vector a -> Int
V.length Vector a
x
   in  if Int
mforall a. Ord a => a -> a -> Bool
<=Int
n
         then forall a. [Vector a] -> Vector a
SV forall a b. (a -> b) -> a -> b
$ (Vector a
xforall a. a -> [a] -> [a]
:) forall a b. (a -> b) -> a -> b
$ forall a. Vector a -> [Vector a]
chunks forall a b. (a -> b) -> a -> b
$ forall a. Storable a => Int -> Vector a -> Vector a
take (Int
nforall a. Num a => a -> a -> a
-Int
m) forall a b. (a -> b) -> a -> b
$ forall a. [Vector a] -> Vector a
SV [Vector a]
xs
         else forall a. Storable a => Vector a -> Vector a
fromChunk (forall a. Storable a => Int -> Vector a -> Vector a
V.take Int
n Vector a
x)

{- |
Take n values from the end of the vector in a memory friendly way.
@takeEnd n xs@ should perform the same as @drop (length xs - n) xs@,
but the latter one would have to materialise @xs@ completely.
In contrast to that
@takeEnd@ should hold only chunks of about @n@ elements at any time point.
-}
{-# INLINE takeEnd #-}
takeEnd :: (Storable a) => Int -> Vector a -> Vector a
takeEnd :: forall a. Storable a => Int -> Vector a -> Vector a
takeEnd Int
n Vector a
xs =
   -- cf. Pattern.drop
   forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
List.foldl (forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a. Storable a => Int -> Vector a -> Vector a
drop) Vector a
xs forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
List.map forall a. Vector a -> Int
V.length forall a b. (a -> b) -> a -> b
$ forall a. Vector a -> [Vector a]
chunks forall a b. (a -> b) -> a -> b
$ forall a. Storable a => Int -> Vector a -> Vector a
drop Int
n Vector a
xs

{-# INLINE drop #-}
drop :: (Storable a) => Int -> Vector a -> Vector a
drop :: forall a. Storable a => Int -> Vector a -> Vector a
drop Int
_ (SV []) = forall a. Storable a => Vector a
empty
drop Int
n (SV (Vector a
x:[Vector a]
xs)) =
   let m :: Int
m = forall a. Vector a -> Int
V.length Vector a
x
   in  if Int
mforall a. Ord a => a -> a -> Bool
<=Int
n
         then forall a. Storable a => Int -> Vector a -> Vector a
drop (Int
nforall a. Num a => a -> a -> a
-Int
m) (forall a. [Vector a] -> Vector a
SV [Vector a]
xs)
         else forall a. [Vector a] -> Vector a
SV (forall a. Storable a => Int -> Vector a -> Vector a
V.drop Int
n Vector a
x forall a. a -> [a] -> [a]
: [Vector a]
xs)

{-# INLINE splitAt #-}
splitAt :: (Storable a) => Int -> Vector a -> (Vector a, Vector a)
splitAt :: forall a. Storable a => Int -> Vector a -> (Vector a, Vector a)
splitAt Int
n0 =
   {- this order of pattern matches is certainly the most lazy one
   > splitAt 4 (pack (chunkSize 2) $ "abcd" List.++ undefined)
   (VectorLazy.fromChunks [Vector.pack "ab",Vector.pack "cd"],VectorLazy.fromChunks *** Exception: Prelude.undefined
   -}
   let recourse :: Int -> [Vector a] -> ([Vector a], [Vector a])
recourse Int
0 [Vector a]
xs = ([], [Vector a]
xs)
       recourse Int
_ [] = ([], [])
       recourse Int
n (Vector a
x:[Vector a]
xs) =
          let m :: Int
m = forall a. Vector a -> Int
V.length Vector a
x
          in  if Int
mforall a. Ord a => a -> a -> Bool
<=Int
n
                then forall a c b. (a -> c) -> (a, b) -> (c, b)
mapFst (Vector a
xforall a. a -> [a] -> [a]
:) forall a b. (a -> b) -> a -> b
$ Int -> [Vector a] -> ([Vector a], [Vector a])
recourse (Int
nforall a. Num a => a -> a -> a
-Int
m) [Vector a]
xs
                else forall a c b d. (a -> c, b -> d) -> (a, b) -> (c, d)
mapPair ((forall a. a -> [a] -> [a]
:[]), (forall a. a -> [a] -> [a]
:[Vector a]
xs)) forall a b. (a -> b) -> a -> b
$ forall a. Storable a => Int -> Vector a -> (Vector a, Vector a)
V.splitAt Int
n Vector a
x
   in  forall a c b d. (a -> c, b -> d) -> (a, b) -> (c, d)
mapPair (forall a. [Vector a] -> Vector a
SV, forall a. [Vector a] -> Vector a
SV) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {a}.
Storable a =>
Int -> [Vector a] -> ([Vector a], [Vector a])
recourse Int
n0 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Vector a -> [Vector a]
chunks



{-# INLINE dropMarginRem #-}
-- I have used this in an inner loop thus I prefer inlining
{- |
@dropMarginRem n m xs@
drops at most the first @m@ elements of @xs@
and ensures that @xs@ still contains @n@ elements.
Additionally returns the number of elements that could not be dropped
due to the margin constraint.
That is @dropMarginRem n m xs == (k,ys)@ implies @length xs - m == length ys - k@.
Requires @length xs >= n@.
-}
dropMarginRem :: (Storable a) => Int -> Int -> Vector a -> (Int, Vector a)
dropMarginRem :: forall a. Storable a => Int -> Int -> Vector a -> (Int, Vector a)
dropMarginRem Int
n Int
m Vector a
xs =
   forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
List.foldl'
      (\(Int
mi,Vector a
xsi) Int
k -> (Int
miforall a. Num a => a -> a -> a
-Int
k, forall a. Storable a => Int -> Vector a -> Vector a
drop Int
k Vector a
xsi))
      (Int
m,Vector a
xs)
      (forall a b. (a -> b) -> [a] -> [b]
List.map forall a. Vector a -> Int
V.length forall a b. (a -> b) -> a -> b
$ forall a. Vector a -> [Vector a]
chunks forall a b. (a -> b) -> a -> b
$ forall a. Storable a => Int -> Vector a -> Vector a
take Int
m forall a b. (a -> b) -> a -> b
$ forall a. Storable a => Int -> Vector a -> Vector a
drop Int
n Vector a
xs)

{-
This implementation does only walk once through the dropped prefix.
It is maximally lazy and minimally space consuming.
-}
{-# INLINE dropMargin #-}
dropMargin :: (Storable a) => Int -> Int -> Vector a -> Vector a
dropMargin :: forall a. Storable a => Int -> Int -> Vector a -> Vector a
dropMargin Int
n Int
m Vector a
xs =
   forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
List.foldl' (forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a. Storable a => Int -> Vector a -> Vector a
drop) Vector a
xs
      (forall a b. (a -> b) -> [a] -> [b]
List.map forall a. Vector a -> Int
V.length forall a b. (a -> b) -> a -> b
$ forall a. Vector a -> [Vector a]
chunks forall a b. (a -> b) -> a -> b
$ forall a. Storable a => Int -> Vector a -> Vector a
take Int
m forall a b. (a -> b) -> a -> b
$ forall a. Storable a => Int -> Vector a -> Vector a
drop Int
n Vector a
xs)



{-# INLINE dropWhile #-}
dropWhile :: (Storable a) => (a -> Bool) -> Vector a -> Vector a
dropWhile :: forall a. Storable a => (a -> Bool) -> Vector a -> Vector a
dropWhile a -> Bool
_ (SV []) = forall a. Storable a => Vector a
empty
dropWhile a -> Bool
p (SV (Vector a
x:[Vector a]
xs)) =
   let y :: Vector a
y = forall a. Storable a => (a -> Bool) -> Vector a -> Vector a
V.dropWhile a -> Bool
p Vector a
x
   in  if forall a. Vector a -> Bool
V.null Vector a
y
         then forall a. Storable a => (a -> Bool) -> Vector a -> Vector a
dropWhile a -> Bool
p (forall a. [Vector a] -> Vector a
SV [Vector a]
xs)
         else forall a. [Vector a] -> Vector a
SV (Vector a
yforall a. a -> [a] -> [a]
:[Vector a]
xs)

{-# INLINE takeWhile #-}
takeWhile :: (Storable a) => (a -> Bool) -> Vector a -> Vector a
takeWhile :: forall a. Storable a => (a -> Bool) -> Vector a -> Vector a
takeWhile a -> Bool
_ (SV []) = forall a. Storable a => Vector a
empty
takeWhile a -> Bool
p (SV (Vector a
x:[Vector a]
xs)) =
   let y :: Vector a
y = forall a. Storable a => (a -> Bool) -> Vector a -> Vector a
V.takeWhile a -> Bool
p Vector a
x
   in  if forall a. Vector a -> Int
V.length Vector a
y forall a. Ord a => a -> a -> Bool
< forall a. Vector a -> Int
V.length Vector a
x
         then forall a. Storable a => Vector a -> Vector a
fromChunk Vector a
y
         else forall a. [Vector a] -> Vector a
SV (Vector a
x forall a. a -> [a] -> [a]
: forall a. Vector a -> [Vector a]
chunks (forall a. Storable a => (a -> Bool) -> Vector a -> Vector a
takeWhile a -> Bool
p (forall a. [Vector a] -> Vector a
SV [Vector a]
xs)))


{-# INLINE span #-}
span, _span :: (Storable a) => (a -> Bool) -> Vector a -> (Vector a, Vector a)
span :: forall a.
Storable a =>
(a -> Bool) -> Vector a -> (Vector a, Vector a)
span a -> Bool
p =
   let recourse :: [Vector a] -> ([Vector a], [Vector a])
recourse [] = ([],[])
       recourse (Vector a
x:[Vector a]
xs) =
          let (Vector a
y,Vector a
z) = forall a.
Storable a =>
(a -> Bool) -> Vector a -> (Vector a, Vector a)
V.span a -> Bool
p Vector a
x
          in  if forall a. Vector a -> Bool
V.null Vector a
z
                then forall a c b. (a -> c) -> (a, b) -> (c, b)
mapFst (Vector a
xforall a. a -> [a] -> [a]
:) ([Vector a] -> ([Vector a], [Vector a])
recourse [Vector a]
xs)
                else (forall a. Vector a -> [Vector a]
chunks forall a b. (a -> b) -> a -> b
$ forall a. Storable a => Vector a -> Vector a
fromChunk Vector a
y, (Vector a
zforall a. a -> [a] -> [a]
:[Vector a]
xs))
   in  forall a c b d. (a -> c, b -> d) -> (a, b) -> (c, d)
mapPair (forall a. [Vector a] -> Vector a
SV, forall a. [Vector a] -> Vector a
SV) forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Vector a] -> ([Vector a], [Vector a])
recourse forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Vector a -> [Vector a]
chunks

_span :: forall a.
Storable a =>
(a -> Bool) -> Vector a -> (Vector a, Vector a)
_span a -> Bool
p =
   let recourse :: Vector a -> (Vector a, Vector a)
recourse (SV []) = (forall a. Storable a => Vector a
empty, forall a. Storable a => Vector a
empty)
       recourse (SV (Vector a
x:[Vector a]
xs)) =
         let (Vector a
y,Vector a
z) = forall a.
Storable a =>
(a -> Bool) -> Vector a -> (Vector a, Vector a)
V.span a -> Bool
p Vector a
x
         in  if forall a. Vector a -> Int
V.length Vector a
y forall a. Eq a => a -> a -> Bool
== Int
0
               then forall a c b. (a -> c) -> (a, b) -> (c, b)
mapFst (forall a. [Vector a] -> Vector a
SV forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Vector a
xforall a. a -> [a] -> [a]
:) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Vector a -> [Vector a]
chunks) (Vector a -> (Vector a, Vector a)
recourse (forall a. [Vector a] -> Vector a
SV [Vector a]
xs))
               else (forall a. [Vector a] -> Vector a
SV [Vector a
y], forall a. [Vector a] -> Vector a
SV (Vector a
zforall a. a -> [a] -> [a]
:[Vector a]
xs))
   in  Vector a -> (Vector a, Vector a)
recourse


-- * other functions


{-# INLINE filter #-}
filter :: (Storable a) => (a -> Bool) -> Vector a -> Vector a
filter :: forall a. Storable a => (a -> Bool) -> Vector a -> Vector a
filter a -> Bool
p =
   forall a. [Vector a] -> Vector a
SV forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (a -> Bool) -> [a] -> [a]
List.filter (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Vector a -> Bool
V.null) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
List.map (forall a. Storable a => (a -> Bool) -> Vector a -> Vector a
V.filter a -> Bool
p) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Vector a -> [Vector a]
chunks


{- |
Generates laziness breaks
wherever one of the input signals has a chunk boundary.
-}
{-# INLINE zipWith #-}
zipWith :: (Storable a, Storable b, Storable c) =>
      (a -> b -> c)
   -> Vector a
   -> Vector b
   -> Vector c
zipWith :: forall a b c.
(Storable a, Storable b, Storable c) =>
(a -> b -> c) -> Vector a -> Vector b -> Vector c
zipWith = forall a b c.
(Storable a, Storable b, Storable c) =>
(Vector a -> Vector c)
-> (Vector b -> Vector c)
-> (a -> b -> c)
-> Vector a
-> Vector b
-> Vector c
zipWithCont (forall a b. a -> b -> a
const forall a. Storable a => Vector a
empty) (forall a b. a -> b -> a
const forall a. Storable a => Vector a
empty)

{-# INLINE zipWith3 #-}
zipWith3 :: (Storable a, Storable b, Storable c, Storable d) =>
      (a -> b -> c -> d)
   -> Vector a
   -> Vector b
   -> Vector c
   -> Vector d
zipWith3 :: forall a b c d.
(Storable a, Storable b, Storable c, Storable d) =>
(a -> b -> c -> d) -> Vector a -> Vector b -> Vector c -> Vector d
zipWith3 a -> b -> c -> d
f Vector a
as0 Vector b
bs0 Vector c
cs0 =
   let recourse :: [Vector a] -> [Vector b] -> [Vector c] -> [Vector d]
recourse at :: [Vector a]
at@(Vector a
a:[Vector a]
_) bt :: [Vector b]
bt@(Vector b
b:[Vector b]
_) ct :: [Vector c]
ct@(Vector c
c:[Vector c]
_) =
          let z :: Vector d
z = forall a b c d.
(Storable a, Storable b, Storable c, Storable d) =>
(a -> b -> c -> d) -> Vector a -> Vector b -> Vector c -> Vector d
V.zipWith3 a -> b -> c -> d
f Vector a
a Vector b
b Vector c
c
              n :: Int
n = forall a. Vector a -> Int
V.length Vector d
z
          in  Vector d
z forall a. a -> [a] -> [a]
: [Vector a] -> [Vector b] -> [Vector c] -> [Vector d]
recourse
                     (forall a. Vector a -> [Vector a]
chunks forall a b. (a -> b) -> a -> b
$ forall a. Storable a => Int -> Vector a -> Vector a
drop Int
n forall a b. (a -> b) -> a -> b
$ forall a. Storable a => [Vector a] -> Vector a
fromChunks [Vector a]
at)
                     (forall a. Vector a -> [Vector a]
chunks forall a b. (a -> b) -> a -> b
$ forall a. Storable a => Int -> Vector a -> Vector a
drop Int
n forall a b. (a -> b) -> a -> b
$ forall a. Storable a => [Vector a] -> Vector a
fromChunks [Vector b]
bt)
                     (forall a. Vector a -> [Vector a]
chunks forall a b. (a -> b) -> a -> b
$ forall a. Storable a => Int -> Vector a -> Vector a
drop Int
n forall a b. (a -> b) -> a -> b
$ forall a. Storable a => [Vector a] -> Vector a
fromChunks [Vector c]
ct)
       recourse [Vector a]
_ [Vector b]
_ [Vector c]
_ = []
   in  forall a. Storable a => [Vector a] -> Vector a
fromChunks forall a b. (a -> b) -> a -> b
$ [Vector a] -> [Vector b] -> [Vector c] -> [Vector d]
recourse (forall a. Vector a -> [Vector a]
chunks Vector a
as0) (forall a. Vector a -> [Vector a]
chunks Vector b
bs0) (forall a. Vector a -> [Vector a]
chunks Vector c
cs0)

{-# INLINE zipWith4 #-}
zipWith4 :: (Storable a, Storable b, Storable c, Storable d, Storable e) =>
      (a -> b -> c -> d -> e)
   -> Vector a
   -> Vector b
   -> Vector c
   -> Vector d
   -> Vector e
zipWith4 :: forall a b c d e.
(Storable a, Storable b, Storable c, Storable d, Storable e) =>
(a -> b -> c -> d -> e)
-> Vector a -> Vector b -> Vector c -> Vector d -> Vector e
zipWith4 a -> b -> c -> d -> e
f Vector a
as0 Vector b
bs0 Vector c
cs0 Vector d
ds0 =
   let recourse :: [Vector a] -> [Vector b] -> [Vector c] -> [Vector d] -> [Vector e]
recourse at :: [Vector a]
at@(Vector a
a:[Vector a]
_) bt :: [Vector b]
bt@(Vector b
b:[Vector b]
_) ct :: [Vector c]
ct@(Vector c
c:[Vector c]
_) dt :: [Vector d]
dt@(Vector d
d:[Vector d]
_) =
          let z :: Vector e
z = forall a b c d e.
(Storable a, Storable b, Storable c, Storable d, Storable e) =>
(a -> b -> c -> d -> e)
-> Vector a -> Vector b -> Vector c -> Vector d -> Vector e
V.zipWith4 a -> b -> c -> d -> e
f Vector a
a Vector b
b Vector c
c Vector d
d
              n :: Int
n = forall a. Vector a -> Int
V.length Vector e
z
          in  Vector e
z forall a. a -> [a] -> [a]
: [Vector a] -> [Vector b] -> [Vector c] -> [Vector d] -> [Vector e]
recourse
                     (forall a. Vector a -> [Vector a]
chunks forall a b. (a -> b) -> a -> b
$ forall a. Storable a => Int -> Vector a -> Vector a
drop Int
n forall a b. (a -> b) -> a -> b
$ forall a. Storable a => [Vector a] -> Vector a
fromChunks [Vector a]
at)
                     (forall a. Vector a -> [Vector a]
chunks forall a b. (a -> b) -> a -> b
$ forall a. Storable a => Int -> Vector a -> Vector a
drop Int
n forall a b. (a -> b) -> a -> b
$ forall a. Storable a => [Vector a] -> Vector a
fromChunks [Vector b]
bt)
                     (forall a. Vector a -> [Vector a]
chunks forall a b. (a -> b) -> a -> b
$ forall a. Storable a => Int -> Vector a -> Vector a
drop Int
n forall a b. (a -> b) -> a -> b
$ forall a. Storable a => [Vector a] -> Vector a
fromChunks [Vector c]
ct)
                     (forall a. Vector a -> [Vector a]
chunks forall a b. (a -> b) -> a -> b
$ forall a. Storable a => Int -> Vector a -> Vector a
drop Int
n forall a b. (a -> b) -> a -> b
$ forall a. Storable a => [Vector a] -> Vector a
fromChunks [Vector d]
dt)
       recourse [Vector a]
_ [Vector b]
_ [Vector c]
_ [Vector d]
_ = []
   in  forall a. Storable a => [Vector a] -> Vector a
fromChunks forall a b. (a -> b) -> a -> b
$
       [Vector a] -> [Vector b] -> [Vector c] -> [Vector d] -> [Vector e]
recourse (forall a. Vector a -> [Vector a]
chunks Vector a
as0) (forall a. Vector a -> [Vector a]
chunks Vector b
bs0) (forall a. Vector a -> [Vector a]
chunks Vector c
cs0) (forall a. Vector a -> [Vector a]
chunks Vector d
ds0)


{-# INLINE zipWithAppend #-}
zipWithAppend :: (Storable a) =>
      (a -> a -> a)
   -> Vector a
   -> Vector a
   -> Vector a
zipWithAppend :: forall a.
Storable a =>
(a -> a -> a) -> Vector a -> Vector a -> Vector a
zipWithAppend = forall a b c.
(Storable a, Storable b, Storable c) =>
(Vector a -> Vector c)
-> (Vector b -> Vector c)
-> (a -> b -> c)
-> Vector a
-> Vector b
-> Vector c
zipWithCont forall a. a -> a
id forall a. a -> a
id

{-# INLINE zipWithCont #-}
zipWithCont :: (Storable a, Storable b, Storable c) =>
      (Vector a -> Vector c)
   -> (Vector b -> Vector c)
   -> (a -> b -> c)
   -> Vector a
   -> Vector b
   -> Vector c
zipWithCont :: forall a b c.
(Storable a, Storable b, Storable c) =>
(Vector a -> Vector c)
-> (Vector b -> Vector c)
-> (a -> b -> c)
-> Vector a
-> Vector b
-> Vector c
zipWithCont Vector a -> Vector c
ga Vector b -> Vector c
gb a -> b -> c
f Vector a
as0 Vector b
bs0 =
   let recourse :: [Vector a] -> [Vector b] -> [Vector c]
recourse at :: [Vector a]
at@(Vector a
a:[Vector a]
_) bt :: [Vector b]
bt@(Vector b
b:[Vector b]
_) =
          let z :: Vector c
z = forall a b c.
(Storable a, Storable b, Storable c) =>
(a -> b -> c) -> Vector a -> Vector b -> Vector c
V.zipWith a -> b -> c
f Vector a
a Vector b
b
              n :: Int
n = forall a. Vector a -> Int
V.length Vector c
z
          in  Vector c
z forall a. a -> [a] -> [a]
: [Vector a] -> [Vector b] -> [Vector c]
recourse
                     (forall a. Vector a -> [Vector a]
chunks forall a b. (a -> b) -> a -> b
$ forall a. Storable a => Int -> Vector a -> Vector a
drop Int
n forall a b. (a -> b) -> a -> b
$ forall a. Storable a => [Vector a] -> Vector a
fromChunks [Vector a]
at)
                     (forall a. Vector a -> [Vector a]
chunks forall a b. (a -> b) -> a -> b
$ forall a. Storable a => Int -> Vector a -> Vector a
drop Int
n forall a b. (a -> b) -> a -> b
$ forall a. Storable a => [Vector a] -> Vector a
fromChunks [Vector b]
bt)
       recourse [] [Vector b]
bs = forall a. Vector a -> [Vector a]
chunks forall a b. (a -> b) -> a -> b
$ Vector b -> Vector c
gb forall a b. (a -> b) -> a -> b
$ forall a. Storable a => [Vector a] -> Vector a
fromChunks [Vector b]
bs
       recourse [Vector a]
as [] = forall a. Vector a -> [Vector a]
chunks forall a b. (a -> b) -> a -> b
$ Vector a -> Vector c
ga forall a b. (a -> b) -> a -> b
$ forall a. Storable a => [Vector a] -> Vector a
fromChunks [Vector a]
as
   in  forall a. Storable a => [Vector a] -> Vector a
fromChunks forall a b. (a -> b) -> a -> b
$ [Vector a] -> [Vector b] -> [Vector c]
recourse (forall a. Vector a -> [Vector a]
chunks Vector a
as0) (forall a. Vector a -> [Vector a]
chunks Vector b
bs0)


{- |
Preserves chunk pattern of the last argument.
-}
{-# INLINE zipWithLastPattern #-}
zipWithLastPattern :: (Storable a, Storable b, Storable c) =>
      (a -> b -> c)
   -> Vector a
   -> Vector b
   -> Vector c
zipWithLastPattern :: forall a b c.
(Storable a, Storable b, Storable c) =>
(a -> b -> c) -> Vector a -> Vector b -> Vector c
zipWithLastPattern a -> b -> c
f =
   forall x y acc.
(Storable x, Storable y) =>
(x -> acc -> Maybe (y, acc)) -> acc -> Vector x -> Vector y
crochetL (\b
y -> forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (forall a c b. (a -> c) -> (a, b) -> (c, b)
mapFst (forall a b c. (a -> b -> c) -> b -> a -> c
flip a -> b -> c
f b
y)) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Storable a => Pointer a -> Maybe (a, Pointer a)
Ptr.viewL) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Storable a => Vector a -> Pointer a
pointer

{- |
Preserves chunk pattern of the last argument.
-}
{-# INLINE zipWithLastPattern3 #-}
zipWithLastPattern3 ::
   (Storable a, Storable b, Storable c, Storable d) =>
   (a -> b -> c -> d) ->
   (Vector a -> Vector b -> Vector c -> Vector d)
zipWithLastPattern3 :: forall a b c d.
(Storable a, Storable b, Storable c, Storable d) =>
(a -> b -> c -> d) -> Vector a -> Vector b -> Vector c -> Vector d
zipWithLastPattern3 a -> b -> c -> d
f Vector a
s0 Vector b
s1 =
   forall x y acc.
(Storable x, Storable y) =>
(x -> acc -> Maybe (y, acc)) -> acc -> Vector x -> Vector y
crochetL (\c
z (Pointer a
xt,Pointer b
yt) ->
      forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2
         (\(a
x,Pointer a
xs) (b
y,Pointer b
ys) -> (a -> b -> c -> d
f a
x b
y c
z, (Pointer a
xs,Pointer b
ys)))
         (forall a. Storable a => Pointer a -> Maybe (a, Pointer a)
Ptr.viewL Pointer a
xt)
         (forall a. Storable a => Pointer a -> Maybe (a, Pointer a)
Ptr.viewL Pointer b
yt))
      (forall a. Storable a => Vector a -> Pointer a
pointer Vector a
s0, forall a. Storable a => Vector a -> Pointer a
pointer Vector b
s1)

{- |
Preserves chunk pattern of the last argument.
-}
{-# INLINE zipWithLastPattern4 #-}
zipWithLastPattern4 ::
   (Storable a, Storable b, Storable c, Storable d, Storable e) =>
   (a -> b -> c -> d -> e) ->
   (Vector a -> Vector b -> Vector c -> Vector d -> Vector e)
zipWithLastPattern4 :: forall a b c d e.
(Storable a, Storable b, Storable c, Storable d, Storable e) =>
(a -> b -> c -> d -> e)
-> Vector a -> Vector b -> Vector c -> Vector d -> Vector e
zipWithLastPattern4 a -> b -> c -> d -> e
f Vector a
s0 Vector b
s1 Vector c
s2 =
   forall x y acc.
(Storable x, Storable y) =>
(x -> acc -> Maybe (y, acc)) -> acc -> Vector x -> Vector y
crochetL (\d
w (Pointer a
xt,Pointer b
yt,Pointer c
zt) ->
      forall (m :: * -> *) a1 a2 a3 r.
Monad m =>
(a1 -> a2 -> a3 -> r) -> m a1 -> m a2 -> m a3 -> m r
liftM3
         (\(a
x,Pointer a
xs) (b
y,Pointer b
ys) (c
z,Pointer c
zs) -> (a -> b -> c -> d -> e
f a
x b
y c
z d
w, (Pointer a
xs,Pointer b
ys,Pointer c
zs)))
         (forall a. Storable a => Pointer a -> Maybe (a, Pointer a)
Ptr.viewL Pointer a
xt)
         (forall a. Storable a => Pointer a -> Maybe (a, Pointer a)
Ptr.viewL Pointer b
yt)
         (forall a. Storable a => Pointer a -> Maybe (a, Pointer a)
Ptr.viewL Pointer c
zt))
      (forall a. Storable a => Vector a -> Pointer a
pointer Vector a
s0, forall a. Storable a => Vector a -> Pointer a
pointer Vector b
s1, forall a. Storable a => Vector a -> Pointer a
pointer Vector c
s2)


{-# INLINE zipWithSize #-}
zipWithSize :: (Storable a, Storable b, Storable c) =>
      ChunkSize
   -> (a -> b -> c)
   -> Vector a
   -> Vector b
   -> Vector c
zipWithSize :: forall a b c.
(Storable a, Storable b, Storable c) =>
ChunkSize -> (a -> b -> c) -> Vector a -> Vector b -> Vector c
zipWithSize ChunkSize
size a -> b -> c
f Vector a
s0 Vector b
s1 =
   forall b a.
Storable b =>
ChunkSize -> (a -> Maybe (b, a)) -> a -> Vector b
unfoldr ChunkSize
size (\(Pointer a
xt,Pointer b
yt) ->
      forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2
         (\(a
x,Pointer a
xs) (b
y,Pointer b
ys) -> (a -> b -> c
f a
x b
y, (Pointer a
xs,Pointer b
ys)))
         (forall a. Storable a => Pointer a -> Maybe (a, Pointer a)
Ptr.viewL Pointer a
xt)
         (forall a. Storable a => Pointer a -> Maybe (a, Pointer a)
Ptr.viewL Pointer b
yt))
      (forall a. Storable a => Vector a -> Pointer a
pointer Vector a
s0, forall a. Storable a => Vector a -> Pointer a
pointer Vector b
s1)

{-# INLINE zipWithSize3 #-}
zipWithSize3 ::
   (Storable a, Storable b, Storable c, Storable d) =>
   ChunkSize -> (a -> b -> c -> d) ->
   (Vector a -> Vector b -> Vector c -> Vector d)
zipWithSize3 :: forall a b c d.
(Storable a, Storable b, Storable c, Storable d) =>
ChunkSize
-> (a -> b -> c -> d)
-> Vector a
-> Vector b
-> Vector c
-> Vector d
zipWithSize3 ChunkSize
size a -> b -> c -> d
f Vector a
s0 Vector b
s1 Vector c
s2 =
   forall b a.
Storable b =>
ChunkSize -> (a -> Maybe (b, a)) -> a -> Vector b
unfoldr ChunkSize
size (\(Pointer a
xt,Pointer b
yt,Pointer c
zt) ->
      forall (m :: * -> *) a1 a2 a3 r.
Monad m =>
(a1 -> a2 -> a3 -> r) -> m a1 -> m a2 -> m a3 -> m r
liftM3
         (\(a
x,Pointer a
xs) (b
y,Pointer b
ys) (c
z,Pointer c
zs) -> (a -> b -> c -> d
f a
x b
y c
z, (Pointer a
xs,Pointer b
ys,Pointer c
zs)))
         (forall a. Storable a => Pointer a -> Maybe (a, Pointer a)
Ptr.viewL Pointer a
xt)
         (forall a. Storable a => Pointer a -> Maybe (a, Pointer a)
Ptr.viewL Pointer b
yt)
         (forall a. Storable a => Pointer a -> Maybe (a, Pointer a)
Ptr.viewL Pointer c
zt))
      (forall a. Storable a => Vector a -> Pointer a
pointer Vector a
s0, forall a. Storable a => Vector a -> Pointer a
pointer Vector b
s1, forall a. Storable a => Vector a -> Pointer a
pointer Vector c
s2)

{-# INLINE zipWithSize4 #-}
zipWithSize4 ::
   (Storable a, Storable b, Storable c, Storable d, Storable e) =>
   ChunkSize -> (a -> b -> c -> d -> e) ->
   (Vector a -> Vector b -> Vector c -> Vector d -> Vector e)
zipWithSize4 :: forall a b c d e.
(Storable a, Storable b, Storable c, Storable d, Storable e) =>
ChunkSize
-> (a -> b -> c -> d -> e)
-> Vector a
-> Vector b
-> Vector c
-> Vector d
-> Vector e
zipWithSize4 ChunkSize
size a -> b -> c -> d -> e
f Vector a
s0 Vector b
s1 Vector c
s2 Vector d
s3 =
   forall b a.
Storable b =>
ChunkSize -> (a -> Maybe (b, a)) -> a -> Vector b
unfoldr ChunkSize
size (\(Pointer a
xt,Pointer b
yt,Pointer c
zt,Pointer d
wt) ->
      forall (m :: * -> *) a1 a2 a3 a4 r.
Monad m =>
(a1 -> a2 -> a3 -> a4 -> r) -> m a1 -> m a2 -> m a3 -> m a4 -> m r
liftM4
         (\(a
x,Pointer a
xs) (b
y,Pointer b
ys) (c
z,Pointer c
zs) (d
w,Pointer d
ws) -> (a -> b -> c -> d -> e
f a
x b
y c
z d
w, (Pointer a
xs,Pointer b
ys,Pointer c
zs,Pointer d
ws)))
         (forall a. Storable a => Pointer a -> Maybe (a, Pointer a)
Ptr.viewL Pointer a
xt)
         (forall a. Storable a => Pointer a -> Maybe (a, Pointer a)
Ptr.viewL Pointer b
yt)
         (forall a. Storable a => Pointer a -> Maybe (a, Pointer a)
Ptr.viewL Pointer c
zt)
         (forall a. Storable a => Pointer a -> Maybe (a, Pointer a)
Ptr.viewL Pointer d
wt))
      (forall a. Storable a => Vector a -> Pointer a
pointer Vector a
s0, forall a. Storable a => Vector a -> Pointer a
pointer Vector b
s1, forall a. Storable a => Vector a -> Pointer a
pointer Vector c
s2, forall a. Storable a => Vector a -> Pointer a
pointer Vector d
s3)


-- * interleaved vectors

{-# INLINE sieve #-}
sieve :: (Storable a) => Int -> Vector a -> Vector a
sieve :: forall a. Storable a => Int -> Vector a -> Vector a
sieve Int
n =
   forall a. Storable a => [Vector a] -> Vector a
fromChunks forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (a -> Bool) -> [a] -> [a]
List.filter (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Vector a -> Bool
V.null) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> b
snd forall b c a. (b -> c) -> (a -> b) -> a -> c
.
   forall (t :: * -> *) s a b.
Traversable t =>
(s -> a -> (s, b)) -> s -> t a -> (s, t b)
List.mapAccumL
      (\Int
offset Vector a
chunk ->
         (forall a. Integral a => a -> a -> a
mod (Int
offset forall a. Num a => a -> a -> a
- forall a. Vector a -> Int
V.length Vector a
chunk) Int
n,
          forall a. Storable a => Int -> Vector a -> Vector a
V.sieve Int
n forall a b. (a -> b) -> a -> b
$ forall a. Storable a => Int -> Vector a -> Vector a
V.drop Int
offset Vector a
chunk)) Int
0 forall b c a. (b -> c) -> (a -> b) -> a -> c
.
   forall a. Vector a -> [Vector a]
chunks

{-# INLINE deinterleave #-}
deinterleave :: (Storable a) => Int -> Vector a -> [Vector a]
deinterleave :: forall a. Storable a => Int -> Vector a -> [Vector a]
deinterleave Int
n =
   forall a b. (a -> b) -> [a] -> [b]
P.map (forall a. Storable a => Int -> Vector a -> Vector a
sieve Int
n) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Int -> [a] -> [a]
P.take Int
n forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. (a -> a) -> a -> [a]
P.iterate (forall a b.
Storable a =>
b -> (a -> Vector a -> b) -> Vector a -> b
switchL forall a. Storable a => Vector a
empty (forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a b. a -> b -> a
const))

{- |
Interleave lazy vectors
while maintaining the chunk pattern of the first vector.
All input vectors must have the same length.
-}
{-# INLINE interleaveFirstPattern #-}
interleaveFirstPattern, _interleaveFirstPattern ::
   (Storable a) => [Vector a] -> Vector a
interleaveFirstPattern :: forall a. Storable a => [Vector a] -> Vector a
interleaveFirstPattern [] = forall a. Storable a => Vector a
empty
interleaveFirstPattern vss :: [Vector a]
vss@(Vector a
vs:[Vector a]
_) =
   let pattern :: [Int]
pattern = forall a b. (a -> b) -> [a] -> [b]
List.map forall a. Vector a -> Int
V.length forall a b. (a -> b) -> a -> b
$ forall a. Vector a -> [Vector a]
chunks Vector a
vs
       split :: Vector a -> [Vector a]
split Vector a
xs =
          forall a b. (a, b) -> b
snd forall a b. (a -> b) -> a -> b
$
          forall (t :: * -> *) s a b.
Traversable t =>
(s -> a -> (s, b)) -> s -> t a -> (s, t b)
List.mapAccumL
             (\Vector a
x Int
n -> forall a b. (a, b) -> (b, a)
swap forall a b. (a -> b) -> a -> b
$ forall a c b. (a -> c) -> (a, b) -> (c, b)
mapFst (forall a. Storable a => [Vector a] -> Vector a
V.concat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Vector a -> [Vector a]
chunks) forall a b. (a -> b) -> a -> b
$ forall a. Storable a => Int -> Vector a -> (Vector a, Vector a)
splitAt Int
n Vector a
x)
             Vector a
xs [Int]
pattern
   in  forall a. Storable a => [Vector a] -> Vector a
fromChunks forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
List.map forall a. Storable a => [Vector a] -> Vector a
V.interleave forall a b. (a -> b) -> a -> b
$
       forall a. [[a]] -> [[a]]
List.transpose forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
List.map forall {a}. Storable a => Vector a -> [Vector a]
split [Vector a]
vss

_interleaveFirstPattern :: forall a. Storable a => [Vector a] -> Vector a
_interleaveFirstPattern [] = forall a. Storable a => Vector a
empty
_interleaveFirstPattern vss :: [Vector a]
vss@(Vector a
vs:[Vector a]
_) =
   forall a. Storable a => [Vector a] -> Vector a
fromChunks forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> b
snd forall b c a. (b -> c) -> (a -> b) -> a -> c
.
   forall (t :: * -> *) s a b.
Traversable t =>
(s -> a -> (s, b)) -> s -> t a -> (s, t b)
List.mapAccumL
      (\[Vector a]
xss Int
n ->
         forall a b. (a, b) -> (b, a)
swap forall a b. (a -> b) -> a -> b
$
         forall a c b. (a -> c) -> (a, b) -> (c, b)
mapFst (forall a. Storable a => [Vector a] -> Vector a
V.interleave forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
List.map (forall a. Storable a => [Vector a] -> Vector a
V.concat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Vector a -> [Vector a]
chunks)) forall a b. (a -> b) -> a -> b
$
         forall a b. [(a, b)] -> ([a], [b])
List.unzip forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
List.map (forall a. Storable a => Int -> Vector a -> (Vector a, Vector a)
splitAt Int
n) [Vector a]
xss)
      [Vector a]
vss forall b c a. (b -> c) -> (a -> b) -> a -> c
.
   forall a b. (a -> b) -> [a] -> [b]
List.map forall a. Vector a -> Int
V.length forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Vector a -> [Vector a]
chunks forall a b. (a -> b) -> a -> b
$ Vector a
vs



{- |
Ensure a minimal length of the list by appending pad values.
-}
{- disabled INLINE pad -}
pad :: (Storable a) => ChunkSize -> a -> Int -> Vector a -> Vector a
pad :: forall a.
Storable a =>
ChunkSize -> a -> Int -> Vector a -> Vector a
pad ChunkSize
size a
y Int
n0 =
   let recourse :: Int -> [Vector a] -> [Vector a]
recourse Int
n [Vector a]
xt =
          if Int
nforall a. Ord a => a -> a -> Bool
<=Int
0
            then [Vector a]
xt
            else
              case [Vector a]
xt of
                 [] -> forall a. Vector a -> [Vector a]
chunks forall a b. (a -> b) -> a -> b
$ forall a. Storable a => ChunkSize -> Int -> a -> Vector a
replicate ChunkSize
size Int
n a
y
                 Vector a
x:[Vector a]
xs -> Vector a
x forall a. a -> [a] -> [a]
: Int -> [Vector a] -> [Vector a]
recourse (Int
n forall a. Num a => a -> a -> a
- forall a. Vector a -> Int
V.length Vector a
x) [Vector a]
xs
   in  forall a. [Vector a] -> Vector a
SV forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> [Vector a] -> [Vector a]
recourse Int
n0 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Vector a -> [Vector a]
chunks

{-# WARNING padAlt "use 'pad' instead" #-}
padAlt :: (Storable a) => ChunkSize -> a -> Int -> Vector a -> Vector a
padAlt :: forall a.
Storable a =>
ChunkSize -> a -> Int -> Vector a -> Vector a
padAlt ChunkSize
size a
x Int
n Vector a
xs =
   forall a. Storable a => Vector a -> Vector a -> Vector a
append Vector a
xs
      (let m :: Int
m = forall a. Vector a -> Int
length Vector a
xs
       in  if Int
nforall a. Ord a => a -> a -> Bool
>Int
m
             then forall a. Storable a => ChunkSize -> Int -> a -> Vector a
replicate ChunkSize
size (Int
nforall a. Num a => a -> a -> a
-Int
m) a
x
             else forall a. Storable a => Vector a
empty)

compact :: (Storable a) => ChunkSize -> Vector a -> Vector a
compact :: forall a. Storable a => ChunkSize -> Vector a -> Vector a
compact ChunkSize
size (SV [Vector a]
xs) =
   forall a. [Vector a] -> Vector a
SV forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
List.map forall a. Storable a => [Vector a] -> Vector a
V.concat forall a b. (a -> b) -> a -> b
$
   forall b a. (b -> b -> Maybe b) -> (a -> b) -> [a] -> [[a]]
compactGen
      (\ChunkSize
x ChunkSize
y -> forall (m :: * -> *) a. MonadPlus m => (a -> Bool) -> m a -> m a
mfilter (forall a. Ord a => a -> a -> Bool
<=ChunkSize
size) forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. Monoid a => a -> a -> a
mappend ChunkSize
x ChunkSize
y)
      (Int -> ChunkSize
ChunkSize forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Vector a -> Int
V.length) [Vector a]
xs

compactGen :: (b -> b -> Maybe b) -> (a -> b) -> [a] -> [[a]]
compactGen :: forall b a. (b -> b -> Maybe b) -> (a -> b) -> [a] -> [[a]]
compactGen b -> b -> Maybe b
_ a -> b
_ [] = []
compactGen b -> b -> Maybe b
plus a -> b
measure (a
x0:[a]
xs0) =
   forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (:) forall a b. (a -> b) -> a -> b
$ forall a c b. (a -> c) -> (a, b) -> (c, b)
mapFst (a
x0forall a. a -> [a] -> [a]
:) forall a b. (a -> b) -> a -> b
$
   forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
List.foldr
      (\a
y b -> ([a], [[a]])
go b
s0 ->
         let ym :: b
ym = a -> b
measure a
y
         in  case b -> b -> Maybe b
plus b
s0 b
ym of
               Just b
s1 -> forall a c b. (a -> c) -> (a, b) -> (c, b)
mapFst (a
yforall a. a -> [a] -> [a]
:) forall a b. (a -> b) -> a -> b
$ b -> ([a], [[a]])
go b
s1
               Maybe b
Nothing -> ([], forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (:) forall a b. (a -> b) -> a -> b
$ forall a c b. (a -> c) -> (a, b) -> (c, b)
mapFst (a
yforall a. a -> [a] -> [a]
:) forall a b. (a -> b) -> a -> b
$ b -> ([a], [[a]])
go b
ym))
      (forall a b. a -> b -> a
const ([], [])) [a]
xs0 (a -> b
measure a
x0)




-- * Helper functions for StorableVector


{-# WARNING cancelNullVector "do not use it" #-}
{-# INLINE cancelNullVector #-}
cancelNullVector :: (V.Vector a, b) -> Maybe (V.Vector a, b)
cancelNullVector :: forall a b. (Vector a, b) -> Maybe (Vector a, b)
cancelNullVector (Vector a, b)
y =
   forall a. Bool -> a -> Maybe a
toMaybe (Bool -> Bool
not (forall a. Vector a -> Bool
V.null (forall a b. (a, b) -> a
fst (Vector a, b)
y))) (Vector a, b)
y

-- if the chunk has length zero, an empty sequence is generated
{-# INLINE fromChunk #-}
fromChunk :: (Storable a) => V.Vector a -> Vector a
fromChunk :: forall a. Storable a => Vector a -> Vector a
fromChunk Vector a
x =
   if forall a. Vector a -> Bool
V.null Vector a
x
     then forall a. Storable a => Vector a
empty
     else forall a. [Vector a] -> Vector a
SV [Vector a
x]



{-
reduceLVector :: Storable x =>
   (x -> acc -> Maybe acc) -> acc -> Vector x -> (acc, Bool)
reduceLVector f acc0 x =
   let recourse i acc =
          if i < V.length x
            then (acc, True)
            else
               maybe
                  (acc, False)
                  (recourse (succ i))
                  (f (V.index x i) acc)
   in  recourse 0 acc0




{- * Fundamental functions -}

{-
Usage of 'unfoldr' seems to be clumsy but that covers all cases,
like different block sizes in source and destination list.
-}
crochetLSize :: (Storable x, Storable y) =>
      ChunkSize
   -> (x -> acc -> Maybe (y, acc))
   -> acc
   -> T x
   -> T y
crochetLSize size f =
   curry (unfoldr size (\(acc,xt) ->
      do (x,xs) <- viewL xt
         (y,acc') <- f x acc
         return (y, (acc',xs))))

crochetListL :: (Storable y) =>
      ChunkSize
   -> (x -> acc -> Maybe (y, acc))
   -> acc
   -> [x]
   -> T y
crochetListL size f =
   curry (unfoldr size (\(acc,xt) ->
      do (x,xs) <- ListHT.viewL xt
         (y,acc') <- f x acc
         return (y, (acc',xs))))



{-# NOINLINE [0] crochetFusionListL #-}
crochetFusionListL :: (Storable y) =>
      ChunkSize
   -> (x -> acc -> Maybe (y, acc))
   -> acc
   -> FList.T x
   -> T y
crochetFusionListL size f =
   curry (unfoldr size (\(acc,xt) ->
      do (x,xs) <- FList.viewL xt
         (y,acc') <- f x acc
         return (y, (acc',xs))))


{-# INLINE [0] reduceL #-}
reduceL :: Storable x =>
   (x -> acc -> Maybe acc) -> acc -> Vector x -> acc
reduceL f acc0 =
   let recourse acc xt =
          case xt of
             [] -> acc
             (x:xs) ->
                 let (acc',continue) = reduceLVector f acc x
                 in  if continue
                       then recourse acc' xs
                       else acc'
   in  recourse acc0 . chunks



{- * Basic functions -}


{-# RULEZ
  "Storable.append/repeat/repeat" forall size x.
      append (repeat size x) (repeat size x) = repeat size x ;

  "Storable.append/repeat/replicate" forall size n x.
      append (repeat size x) (replicate size n x) = repeat size x ;

  "Storable.append/replicate/repeat" forall size n x.
      append (replicate size n x) (repeat size x) = repeat size x ;

  "Storable.append/replicate/replicate" forall size n m x.
      append (replicate size n x) (replicate size m x) =
         replicate size (n+m) x ;

  "Storable.mix/repeat/repeat" forall size x y.
      mix (repeat size x) (repeat size y) = repeat size (x+y) ;

  #-}

{-# RULES
  "Storable.length/cons" forall x xs.
      length (cons x xs) = 1 + length xs ;

  "Storable.length/map" forall f xs.
      length (map f xs) = length xs ;

  "Storable.map/cons" forall f x xs.
      map f (cons x xs) = cons (f x) (map f xs) ;

  "Storable.map/repeat" forall size f x.
      map f (repeat size x) = repeat size (f x) ;

  "Storable.map/replicate" forall size f x n.
      map f (replicate size n x) = replicate size n (f x) ;

  "Storable.map/repeat" forall size f x.
      map f (repeat size x) = repeat size (f x) ;

  {-
  This can make things worse, if 'map' is applied to replicate,
  since this can use of sharing.
  It can also destroy the more important map/unfoldr fusion in
    take n . map f . unfoldr g

  "Storable.take/map" forall n f x.
      take n (map f x) = map f (take n x) ;
  -}

  "Storable.take/repeat" forall size n x.
      take n (repeat size x) = replicate size n x ;

  "Storable.take/take" forall n m xs.
      take n (take m xs) = take (min n m) xs ;

  "Storable.drop/drop" forall n m xs.
      drop n (drop m xs) = drop (n+m) xs ;

  "Storable.drop/take" forall n m xs.
      drop n (take m xs) = take (max 0 (m-n)) (drop n xs) ;

  "Storable.map/mapAccumL/snd" forall g f acc0 xs.
      map g (snd (mapAccumL f acc0 xs)) =
         snd (mapAccumL (\acc a -> mapSnd g (f acc a)) acc0 xs) ;

  #-}

{- GHC says this is an orphaned rule
  "Storable.map/mapAccumL/mapSnd" forall g f acc0 xs.
      mapSnd (map g) (mapAccumL f acc0 xs) =
         mapAccumL (\acc a -> mapSnd g (f acc a)) acc0 xs ;
-}


{- * Fusable functions -}

scanLCrochet :: (Storable a, Storable b) =>
   (a -> b -> a) -> a -> Vector b -> Vector a
scanLCrochet f start =
   cons start .
   crochetL (\x acc -> let y = f acc x in Just (y, y)) start

{-# INLINE mapCrochet #-}
mapCrochet :: (Storable a, Storable b) => (a -> b) -> (Vector a -> Vector b)
mapCrochet f = crochetL (\x _ -> Just (f x, ())) ()

{-# INLINE takeCrochet #-}
takeCrochet :: Storable a => Int -> Vector a -> Vector a
takeCrochet = crochetL (\x n -> toMaybe (n>0) (x, pred n))

{-# INLINE repeatUnfoldr #-}
repeatUnfoldr :: Storable a => ChunkSize -> a -> Vector a
repeatUnfoldr size = iterate size id

{-# INLINE replicateCrochet #-}
replicateCrochet :: Storable a => ChunkSize -> Int -> a -> Vector a
replicateCrochet size n = takeCrochet n . repeat size




{-
The "fromList/drop" rule is not quite accurate
because the chunk borders are moved.
Maybe 'ChunkSize' better is a list of chunks sizes.
-}

{-# RULEZ
  "fromList/zipWith"
    forall size f (as :: Storable a => [a]) (bs :: Storable a => [a]).
     fromList size (List.zipWith f as bs) =
        zipWith size f (fromList size as) (fromList size bs) ;

  "fromList/drop" forall as n size.
     fromList size (List.drop n as) =
        drop n (fromList size as) ;
  #-}



{- * Fused functions -}

type Unfoldr s a = (s -> Maybe (a,s), s)

{-# INLINE zipWithUnfoldr2 #-}
zipWithUnfoldr2 :: Storable z =>
      ChunkSize
   -> (x -> y -> z)
   -> Unfoldr a x
   -> Unfoldr b y
   -> T z
zipWithUnfoldr2 size h (f,a) (g,b) =
   unfoldr size
      (\(a0,b0) -> liftM2 (\(x,a1) (y,b1) -> (h x y, (a1,b1))) (f a0) (g b0))
--      (uncurry (liftM2 (\(x,a1) (y,b1) -> (h x y, (a1,b1)))) . (f *** g))
      (a,b)

{- done by takeCrochet
{-# INLINE mapUnfoldr #-}
mapUnfoldr :: (Storable x, Storable y) =>
      ChunkSize
   -> (x -> y)
   -> Unfoldr a x
   -> T y
mapUnfoldr size g (f,a) =
   unfoldr size (fmap (mapFst g) . f) a
-}

{-# INLINE dropUnfoldr #-}
dropUnfoldr :: Storable x =>
      ChunkSize
   -> Int
   -> Unfoldr a x
   -> T x
dropUnfoldr size n (f,a0) =
   maybe
      empty
      (unfoldr size f)
      (nest n (\a -> fmap snd . f =<< a) (Just a0))


{- done by takeCrochet
{-# INLINE takeUnfoldr #-}
takeUnfoldr :: Storable x =>
      ChunkSize
   -> Int
   -> Unfoldr a x
   -> T x
takeUnfoldr size n0 (f,a0) =
   unfoldr size
      (\(a,n) ->
         do guard (n>0)
            (x,a') <- f a
            return (x, (a', pred n)))
      (a0,n0)
-}


lengthUnfoldr :: Storable x =>
      Unfoldr a x
   -> Int
lengthUnfoldr (f,a0) =
   let recourse n a =
          maybe n (recourse (succ n) . snd) (f a)
   in  recourse 0 a0


{-# INLINE zipWithUnfoldr #-}
zipWithUnfoldr ::
   (Storable b, Storable c) =>
      (acc -> Maybe (a, acc))
   -> (a -> b -> c)
   -> acc
   -> T b -> T c
zipWithUnfoldr f h a y =
   crochetL (\y0 a0 ->
       do (x0,a1) <- f a0
          Just (h x0 y0, a1)) a y

{-# INLINE zipWithCrochetL #-}
zipWithCrochetL ::
   (Storable x, Storable b, Storable c) =>
      ChunkSize
   -> (x -> acc -> Maybe (a, acc))
   -> (a -> b -> c)
   -> acc
   -> T x -> T b -> T c
zipWithCrochetL size f h a x y =
   crochetL (\(x0,y0) a0 ->
       do (z0,a1) <- f x0 a0
          Just (h z0 y0, a1))
      a (zip size x y)


{-# INLINE crochetLCons #-}
crochetLCons ::
   (Storable a, Storable b) =>
      (a -> acc -> Maybe (b, acc))
   -> acc
   -> a -> T a -> T b
crochetLCons f a0 x xs =
   maybe
      empty
      (\(y,a1) -> cons y (crochetL f a1 xs))
      (f x a0)

{-# INLINE reduceLCons #-}
reduceLCons ::
   (Storable a) =>
      (a -> acc -> Maybe acc)
   -> acc
   -> a -> T a -> acc
reduceLCons f a0 x xs =
   maybe a0 (flip (reduceL f) xs) (f x a0)





{-# RULES
  "Storable.zipWith/share" forall size (h :: a->a->b) (x :: T a).
     zipWith size h x x = map (\xi -> h xi xi) x ;

--  "Storable.map/zipWith" forall size (f::c->d) (g::a->b->c) (x::T a) (y::T b).
  "Storable.map/zipWith" forall size f g x y.
     map f (zipWith size g x y) =
        zipWith size (\xi yi -> f (g xi yi)) x y ;

  -- this rule lets map run on a different block structure
  "Storable.zipWith/map,*" forall size f g x y.
     zipWith size g (map f x) y =
        zipWith size (\xi yi -> g (f xi) yi) x y ;

  "Storable.zipWith/*,map" forall size f g x y.
     zipWith size g x (map f y) =
        zipWith size (\xi yi -> g xi (f yi)) x y ;


  "Storable.drop/unfoldr" forall size f a n.
     drop n (unfoldr size f a) =
        dropUnfoldr size n (f,a) ;

  "Storable.take/unfoldr" forall size f a n.
     take n (unfoldr size f a) =
--        takeUnfoldr size n (f,a) ;
        takeCrochet n (unfoldr size f a) ;

  "Storable.length/unfoldr" forall size f a.
     length (unfoldr size f a) = lengthUnfoldr (f,a) ;

  "Storable.map/unfoldr" forall size g f a.
     map g (unfoldr size f a) =
--        mapUnfoldr size g (f,a) ;
        mapCrochet g (unfoldr size f a) ;

  "Storable.map/iterate" forall size g f a.
     map g (iterate size f a) =
        mapCrochet g (iterate size f a) ;

{-
  "Storable.zipWith/unfoldr,unfoldr" forall sizeA sizeB f g h a b n.
     zipWith n h (unfoldr sizeA f a) (unfoldr sizeB g b) =
        zipWithUnfoldr2 n h (f,a) (g,b) ;
-}

  -- block boundaries are changed here, so it changes lazy behaviour
  "Storable.zipWith/unfoldr,*" forall sizeA sizeB f h a y.
     zipWith sizeA h (unfoldr sizeB f a) y =
        zipWithUnfoldr f h a y ;

  -- block boundaries are changed here, so it changes lazy behaviour
  "Storable.zipWith/*,unfoldr" forall sizeA sizeB f h a y.
     zipWith sizeA h y (unfoldr sizeB f a) =
        zipWithUnfoldr f (flip h) a y ;

  "Storable.crochetL/unfoldr" forall size f g a b.
     crochetL g b (unfoldr size f a) =
        unfoldr size (\(a0,b0) ->
            do (y0,a1) <- f a0
               (z0,b1) <- g y0 b0
               Just (z0, (a1,b1))) (a,b) ;

  "Storable.reduceL/unfoldr" forall size f g a b.
     reduceL g b (unfoldr size f a) =
        snd
          (FList.recourse (\(a0,b0) ->
              do (y,a1) <- f a0
                 b1 <- g y b0
                 Just (a1, b1)) (a,b)) ;

  "Storable.crochetL/cons" forall g b x xs.
     crochetL g b (cons x xs) =
        crochetLCons g b x xs ;

  "Storable.reduceL/cons" forall g b x xs.
     reduceL g b (cons x xs) =
        reduceLCons g b x xs ;




  "Storable.take/crochetL" forall f a x n.
     take n (crochetL f a x) =
        takeCrochet n (crochetL f a x) ;

  "Storable.length/crochetL" forall f a x.
     length (crochetL f a x) = length x ;

  "Storable.map/crochetL" forall g f a x.
     map g (crochetL f a x) =
        mapCrochet g (crochetL f a x) ;

  "Storable.zipWith/crochetL,*" forall size f h a x y.
     zipWith size h (crochetL f a x) y =
        zipWithCrochetL size f h a x y ;

  "Storable.zipWith/*,crochetL" forall size f h a x y.
     zipWith size h y (crochetL f a x) =
        zipWithCrochetL size f (flip h) a x y ;

  "Storable.crochetL/crochetL" forall f g a b x.
     crochetL g b (crochetL f a x) =
        crochetL (\x0 (a0,b0) ->
            do (y0,a1) <- f x0 a0
               (z0,b1) <- g y0 b0
               Just (z0, (a1,b1))) (a,b) x ;

  "Storable.reduceL/crochetL" forall f g a b x.
     reduceL g b (crochetL f a x) =
        snd
          (reduceL (\x0 (a0,b0) ->
              do (y,a1) <- f x0 a0
                 b1 <- g y b0
                 Just (a1, b1)) (a,b) x) ;
  #-}

-}

{- * IO -}

{- |
Read the rest of a file lazily and
provide the reason of termination as IOError.
If IOError is EOF (check with @System.Error.isEOFError err@),
then the file was read successfully.
Only access the final IOError after you have consumed the file contents,
since finding out the terminating reason forces to read the entire file.
Make also sure you read the file completely,
because it is only closed when the file end is reached
(or an exception is encountered).

TODO:
In ByteString.Lazy the chunk size is reduced
if data is not immediately available.
Maybe we should adapt that behaviour
but when working with realtime streams
that may mean that the chunks are very small.
-}
{-
ToDo:
It might be better to let the user close the file manually
after he finished processing the file.
-}
hGetContentsAsync :: Storable a =>
   ChunkSize -> Handle -> IO (IOError, Vector a)
hGetContentsAsync :: forall a.
Storable a =>
ChunkSize -> Handle -> IO (IOError, Vector a)
hGetContentsAsync (ChunkSize Int
size) Handle
h =
   let go :: IO (IOError, [Vector a])
go =
          forall a. IO a -> IO a
Unsafe.interleaveIO forall a b. (a -> b) -> a -> b
$
          forall a b c. (a -> b -> c) -> b -> a -> c
flip forall e a. Exception e => IO a -> (e -> IO a) -> IO a
catch (\IOError
err -> forall (m :: * -> *) a. Monad m => a -> m a
return (IOError
err,[])) forall a b. (a -> b) -> a -> b
$
          do Vector a
v <- forall a. Storable a => Handle -> Int -> IO (Vector a)
V.hGet Handle
h Int
size
             if forall a. Vector a -> Bool
V.null Vector a
v
               then Handle -> IO ()
hClose Handle
h forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
                    forall (m :: * -> *) a. Monad m => a -> m a
return (IOErrorType -> String -> Maybe Handle -> Maybe String -> IOError
Exc.mkIOError IOErrorType
Exc.eofErrorType
                      String
"StorableVector.Lazy.hGetContentsAsync" (forall a. a -> Maybe a
Just Handle
h) forall a. Maybe a
Nothing, [])
               else forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall b c a. (b -> c) -> (a, b) -> (a, c)
mapSnd (Vector a
vforall a. a -> [a] -> [a]
:)) IO (IOError, [Vector a])
go
{-
          Unsafe.interleaveIO $
          flip catch (\err -> return (err,[])) $
          liftM2 (\ chunk ~(err,rest) -> (err,chunk:rest))
             (V.hGet h size) go
-}
   in  forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall b c a. (b -> c) -> (a, b) -> (a, c)
mapSnd forall a. [Vector a] -> Vector a
SV) IO (IOError, [Vector a])
go

hGetContentsSync :: Storable a =>
   ChunkSize -> Handle -> IO (Vector a)
hGetContentsSync :: forall a. Storable a => ChunkSize -> Handle -> IO (Vector a)
hGetContentsSync (ChunkSize Int
size) Handle
h =
   let go :: IO [Vector a]
go =
          do Vector a
v <- forall a. Storable a => Handle -> Int -> IO (Vector a)
V.hGet Handle
h Int
size
             if forall a. Vector a -> Bool
V.null Vector a
v
               then forall (m :: * -> *) a. Monad m => a -> m a
return []
               else forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Vector a
vforall a. a -> [a] -> [a]
:) IO [Vector a]
go
   in  forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. [Vector a] -> Vector a
SV IO [Vector a]
go

hPut :: Storable a => Handle -> Vector a -> IO ()
hPut :: forall a. Storable a => Handle -> Vector a -> IO ()
hPut Handle
h = forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (forall a. Storable a => Handle -> Vector a -> IO ()
V.hPut Handle
h) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Vector a -> [Vector a]
chunks

{-
*Data.StorableVector.Lazy> print . mapSnd (length :: Vector Data.Int.Int16 -> Int) =<< readFileAsync (ChunkSize 1000) "dist/build/libHSstorablevector-0.1.3.a"
(dist/build/libHSstorablevector-0.1.3.a: hGetBuf: illegal operation (handle is closed),0)
-}
{- |
The file can only closed after all values are consumed.
That is you must always assert that you consume all elements of the stream,
and that no values are missed due to lazy evaluation.
This requirement makes this function useless in many applications.
-}
readFileAsync :: Storable a => ChunkSize -> FilePath -> IO (IOError, Vector a)
readFileAsync :: forall a.
Storable a =>
ChunkSize -> String -> IO (IOError, Vector a)
readFileAsync ChunkSize
size String
path =
   String -> IOMode -> IO Handle
openBinaryFile String
path IOMode
ReadMode forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall a.
Storable a =>
ChunkSize -> Handle -> IO (IOError, Vector a)
hGetContentsAsync ChunkSize
size

writeFile :: Storable a => FilePath -> Vector a -> IO ()
writeFile :: forall a. Storable a => String -> Vector a -> IO ()
writeFile String
path =
   forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
bracket (String -> IOMode -> IO Handle
openBinaryFile String
path IOMode
WriteMode) Handle -> IO ()
hClose forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a. Storable a => Handle -> Vector a -> IO ()
hPut

appendFile :: Storable a => FilePath -> Vector a -> IO ()
appendFile :: forall a. Storable a => String -> Vector a -> IO ()
appendFile String
path =
   forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
bracket (String -> IOMode -> IO Handle
openBinaryFile String
path IOMode
AppendMode) Handle -> IO ()
hClose forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a. Storable a => Handle -> Vector a -> IO ()
hPut

interact :: Storable a => ChunkSize -> (Vector a -> Vector a) -> IO ()
interact :: forall a.
Storable a =>
ChunkSize -> (Vector a -> Vector a) -> IO ()
interact (ChunkSize Int
size) Vector a -> Vector a
f =
   let -- almost duplicate of hGetContentsSync
       hGetContents :: Handle -> IO [Vector a]
hGetContents Handle
h =
          let go :: IO [Vector a]
go =
                 forall a. IO a -> IO a
Unsafe.interleaveIO forall a b. (a -> b) -> a -> b
$
                 do Vector a
v <- forall a. Storable a => Handle -> Int -> IO (Vector a)
V.hGet Handle
h Int
size
                    if forall a. Vector a -> Bool
V.null Vector a
v
                      then forall (m :: * -> *) a. Monad m => a -> m a
return []
                      else forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Vector a
vforall a. a -> [a] -> [a]
:) IO [Vector a]
go
          in  IO [Vector a]
go
   in  forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (forall a. Storable a => Handle -> Vector a -> IO ()
V.hPut Handle
IO.stdout) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Vector a -> [Vector a]
chunks forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector a -> Vector a
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [Vector a] -> Vector a
SV forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall {a}. Storable a => Handle -> IO [Vector a]
hGetContents Handle
IO.stdin



{-# NOINLINE moduleError #-}
moduleError :: String -> String -> a
moduleError :: forall a. String -> String -> a
moduleError String
fun String
msg =
   forall a. HasCallStack => String -> a
error (String
"Data.StorableVector.Lazy." forall a. [a] -> [a] -> [a]
List.++ String
fun forall a. [a] -> [a] -> [a]
List.++ Char
':'forall a. a -> [a] -> [a]
:Char
' 'forall a. a -> [a] -> [a]
:String
msg)