#include "phases.h"
module Data.Vector.IVector (
IVector,
length, null,
empty, singleton, cons, snoc, replicate, (++), copy,
(!), head, last, indexM, headM, lastM,
slice, init, tail, take, drop,
accum, (//), update, backpermute, reverse,
map, concatMap,
zipWith, zipWith3, zip, zip3, unzip, unzip3,
eq, cmp,
filter, takeWhile, dropWhile,
elem, notElem, find, findIndex,
foldl, foldl1, foldl', foldl1', foldr, foldr1,
and, or, sum, product, maximum, minimum,
unfoldr,
prescanl, prescanl',
enumFromTo, enumFromThenTo,
toList, fromList,
stream, unstream,
new,
unsafeSlice, unsafeIndexM,
vlength, vnew
) where
import qualified Data.Vector.MVector as MVector
import Data.Vector.MVector ( MVector )
import qualified Data.Vector.MVector.New as New
import Data.Vector.MVector.New ( New )
import qualified Data.Vector.Fusion.Stream as Stream
import Data.Vector.Fusion.Stream ( Stream, MStream )
import qualified Data.Vector.Fusion.Stream.Monadic as MStream
import Data.Vector.Fusion.Stream.Size
import Data.Vector.Fusion.Util
import Control.Exception ( assert )
import Prelude hiding ( length, null,
replicate, (++),
head, last,
init, tail, take, drop, reverse,
map, concatMap,
zipWith, zipWith3, zip, zip3, unzip, unzip3,
filter, takeWhile, dropWhile,
elem, notElem,
foldl, foldl1, foldr, foldr1,
and, or, sum, product, maximum, minimum,
enumFromTo, enumFromThenTo )
class IVector v a where
vnew :: (forall mv m. MVector mv m a => m (mv a)) -> v a
vlength :: v a -> Int
unsafeSlice :: v a -> Int -> Int -> v a
unsafeIndexM :: Monad m => v a -> Int -> m a
new :: IVector v a => New a -> v a
new m = new' undefined m
new' :: IVector v a => v a -> New a -> v a
new' _ m = vnew (New.run m)
stream :: IVector v a => v a -> Stream a
stream v = v `seq` (Stream.unfoldr get 0 `Stream.sized` Exact n)
where
n = length v
get i | i < n = case unsafeIndexM v i of Box x -> Just (x, i+1)
| otherwise = Nothing
unstream :: IVector v a => Stream a -> v a
unstream s = new (New.unstream s)
inplace :: (forall m. Monad m => MStream m a -> MStream m a)
-> Stream a -> Stream a
inplace f s = f s
length :: IVector v a => v a -> Int
length v = vlength v
null :: IVector v a => v a -> Bool
null v = vlength v == 0
empty :: IVector v a => v a
empty = unstream Stream.empty
singleton :: IVector v a => a -> v a
singleton x = unstream (Stream.singleton x)
replicate :: IVector v a => Int -> a -> v a
replicate n = unstream . Stream.replicate n
cons :: IVector v a => a -> v a -> v a
cons x = unstream . Stream.cons x . stream
snoc :: IVector v a => v a -> a -> v a
snoc v = unstream . Stream.snoc (stream v)
infixr 5 ++
(++) :: IVector v a => v a -> v a -> v a
v ++ w = unstream (stream v Stream.++ stream w)
copy :: IVector v a => v a -> v a
copy = unstream . stream
(!) :: IVector v a => v a -> Int -> a
v ! i = assert (i >= 0 && i < length v)
$ unId (unsafeIndexM v i)
head :: IVector v a => v a -> a
head v = v ! 0
last :: IVector v a => v a -> a
last v = v ! (length v 1)
indexM :: (IVector v a, Monad m) => v a -> Int -> m a
indexM v i = assert (i >= 0 && i < length v)
$ unsafeIndexM v i
headM :: (IVector v a, Monad m) => v a -> m a
headM v = indexM v 0
lastM :: (IVector v a, Monad m) => v a -> m a
lastM v = indexM v (length v 1)
slice :: IVector v a => v a -> Int
-> Int
-> v a
slice v i n = assert (i >= 0 && n >= 0 && i+n <= length v)
$ unsafeSlice v i n
init :: IVector v a => v a -> v a
init v = slice v 0 (length v 1)
tail :: IVector v a => v a -> v a
tail v = slice v 1 (length v 1)
take :: IVector v a => Int -> v a -> v a
take n v = slice v 0 (min n' (length v))
where n' = max n 0
drop :: IVector v a => Int -> v a -> v a
drop n v = slice v (min n' len) (max 0 (len n'))
where n' = max n 0
len = length v
accum :: IVector v a => (a -> b -> a) -> v a -> [(Int,b)] -> v a
accum f v us = new (New.accum f (New.unstream (stream v))
(Stream.fromList us))
(//) :: IVector v a => v a -> [(Int, a)] -> v a
v // us = new (New.update (New.unstream (stream v))
(Stream.fromList us))
update :: (IVector v a, IVector v (Int, a)) => v a -> v (Int, a) -> v a
update v w = new (New.update (New.unstream (stream v)) (stream w))
backpermute :: (IVector v a, IVector v Int) => v a -> v Int -> v a
backpermute v is = unstream
. MStream.trans (Id . unBox)
. MStream.mapM (indexM v)
. MStream.trans (Box . unId)
$ stream is
reverse :: (IVector v a) => v a -> v a
reverse = new . New.reverse . New.unstream . stream
map :: (IVector v a, IVector v b) => (a -> b) -> v a -> v b
map f = unstream . Stream.map f . stream
inplace_map :: IVector v a => (a -> a) -> v a -> v a
inplace_map f = unstream . inplace (MStream.map f) . stream
concatMap :: (IVector v a, IVector v b) => (a -> v b) -> v a -> v b
concatMap f = unstream . Stream.concatMap (stream . f) . stream
zipWith :: (IVector v a, IVector v b, IVector v c) => (a -> b -> c) -> v a -> v b -> v c
zipWith f xs ys = unstream (Stream.zipWith f (stream xs) (stream ys))
zipWith3 :: (IVector v a, IVector v b, IVector v c, IVector v d) => (a -> b -> c -> d) -> v a -> v b -> v c -> v d
zipWith3 f xs ys zs = unstream (Stream.zipWith3 f (stream xs) (stream ys) (stream zs))
zip :: (IVector v a, IVector v b, IVector v (a,b)) => v a -> v b -> v (a, b)
zip = zipWith (,)
zip3 :: (IVector v a, IVector v b, IVector v c, IVector v (a, b, c)) => v a -> v b -> v c -> v (a, b, c)
zip3 = zipWith3 (,,)
unzip :: (IVector v a, IVector v b, IVector v (a,b)) => v (a, b) -> (v a, v b)
unzip xs = (map fst xs, map snd xs)
unzip3 :: (IVector v a, IVector v b, IVector v c, IVector v (a, b, c)) => v (a, b, c) -> (v a, v b, v c)
unzip3 xs = (map (\(a, b, c) -> a) xs, map (\(a, b, c) -> b) xs, map (\(a, b, c) -> c) xs)
eq :: (IVector v a, Eq a) => v a -> v a -> Bool
xs `eq` ys = stream xs == stream ys
cmp :: (IVector v a, Ord a) => v a -> v a -> Ordering
cmp xs ys = compare (stream xs) (stream ys)
filter :: IVector v a => (a -> Bool) -> v a -> v a
filter f = unstream . inplace (MStream.filter f) . stream
takeWhile :: IVector v a => (a -> Bool) -> v a -> v a
takeWhile f = unstream . Stream.takeWhile f . stream
dropWhile :: IVector v a => (a -> Bool) -> v a -> v a
dropWhile f = unstream . Stream.dropWhile f . stream
infix 4 `elem`
elem :: (IVector v a, Eq a) => a -> v a -> Bool
elem x = Stream.elem x . stream
infix 4 `notElem`
notElem :: (IVector v a, Eq a) => a -> v a -> Bool
notElem x = Stream.notElem x . stream
find :: IVector v a => (a -> Bool) -> v a -> Maybe a
find f = Stream.find f . stream
findIndex :: IVector v a => (a -> Bool) -> v a -> Maybe Int
findIndex f = Stream.findIndex f . stream
foldl :: IVector v b => (a -> b -> a) -> a -> v b -> a
foldl f z = Stream.foldl f z . stream
foldl1 :: IVector v a => (a -> a -> a) -> v a -> a
foldl1 f = Stream.foldl1 f . stream
foldl' :: IVector v b => (a -> b -> a) -> a -> v b -> a
foldl' f z = Stream.foldl' f z . stream
foldl1' :: IVector v a => (a -> a -> a) -> v a -> a
foldl1' f = Stream.foldl1' f . stream
foldr :: IVector v a => (a -> b -> b) -> b -> v a -> b
foldr f z = Stream.foldr f z . stream
foldr1 :: IVector v a => (a -> a -> a) -> v a -> a
foldr1 f = Stream.foldr1 f . stream
and :: IVector v Bool => v Bool -> Bool
and = Stream.and . stream
or :: IVector v Bool => v Bool -> Bool
or = Stream.or . stream
sum :: (IVector v a, Num a) => v a -> a
sum = Stream.foldl' (+) 0 . stream
product :: (IVector v a, Num a) => v a -> a
product = Stream.foldl' (*) 1 . stream
maximum :: (IVector v a, Ord a) => v a -> a
maximum = Stream.foldl1' max . stream
minimum :: (IVector v a, Ord a) => v a -> a
minimum = Stream.foldl1' min . stream
unfoldr :: IVector v a => (b -> Maybe (a, b)) -> b -> v a
unfoldr f = unstream . Stream.unfoldr f
prescanl :: (IVector v a, IVector v b) => (a -> b -> a) -> a -> v b -> v a
prescanl f z = unstream . Stream.prescanl f z . stream
inplace_prescanl :: IVector v a => (a -> a -> a) -> a -> v a -> v a
inplace_prescanl f z = unstream . inplace (MStream.prescanl f z) . stream
prescanl' :: (IVector v a, IVector v b) => (a -> b -> a) -> a -> v b -> v a
prescanl' f z = unstream . Stream.prescanl' f z . stream
inplace_prescanl' :: IVector v a => (a -> a -> a) -> a -> v a -> v a
inplace_prescanl' f z = unstream . inplace (MStream.prescanl' f z) . stream
enumFromTo :: (IVector v a, Enum a) => a -> a -> v a
enumFromTo from to = from `seq` to `seq` unfoldr enumFromTo_go (fromEnum from)
where
to_i = fromEnum to
enumFromTo_go i | i <= to_i = Just (toEnum i, i + 1)
| otherwise = Nothing
enumFromThenTo :: (IVector v a, Enum a) => a -> a -> a -> v a
enumFromThenTo from next to = from `seq` next `seq` to `seq` unfoldr enumFromThenTo_go from_i
where
from_i = fromEnum from
to_i = fromEnum to
step_i = fromEnum next from_i
enumFromThenTo_go i | i <= to_i = Just (toEnum i, i + step_i)
| otherwise = Nothing
toList :: IVector v a => v a -> [a]
toList = Stream.toList . stream
fromList :: IVector v a => [a] -> v a
fromList = unstream . Stream.fromList