packages feed

vector 0.2 → 0.3

raw patch · 17 files changed

+1576/−295 lines, 17 filesdep ~basedep ~ghc

Dependency ranges changed: base, ghc

Files

Data/Vector.hs view
@@ -13,11 +13,57 @@ --  module Data.Vector (-  Vector(..), module Data.Vector.IVector+  Vector,++  -- * Length information+  length, null,++  -- * Construction+  empty, singleton, cons, snoc, replicate, (++), copy,++  -- * Accessing individual elements+  (!), head, last, indexM, headM, lastM,++  -- * Subvectors+  slice, init, tail, take, drop,++  -- * Permutations+  accum, (//), update, backpermute, reverse,++  -- * Mapping+  map, concatMap,++  -- * Zipping and unzipping+  zipWith, zipWith3, zip, zip3, unzip, unzip3,++  -- * Filtering+  filter, takeWhile, dropWhile,++  -- * Searching+  elem, notElem, find, findIndex,++  -- * Folding+  foldl, foldl1, foldl', foldl1', foldr, foldr1,++  -- * Specialised folds+  and, or, sum, product, maximum, minimum,++  -- * Unfolding+  unfoldr,++  -- * Scans+  prescanl, prescanl',++  -- * Enumeration+  enumFromTo, enumFromThenTo,++  -- * Conversion to/from lists+  toList, fromList ) where -import           Data.Vector.IVector-import qualified Data.Vector.Mutable as Mut+import           Data.Vector.IVector ( IVector(..) )+import qualified Data.Vector.IVector    as IV+import qualified Data.Vector.Mutable.ST as Mut  import Control.Monad.ST ( runST ) @@ -25,10 +71,27 @@ import GHC.Prim ( Array#, unsafeFreezeArray#, indexArray#, (+#) ) import GHC.Base ( Int(..) ) +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, minimum, maximum,+                        enumFromTo, enumFromThenTo )++import qualified Prelude+ data Vector a = Vector {-# UNPACK #-} !Int                        {-# UNPACK #-} !Int                                       (Array# a) +instance Show a => Show (Vector a) where+    show = (Prelude.++ " :: Data.Vector.Vector") . ("fromList " Prelude.++) . show . toList+ instance IVector Vector a where   {-# INLINE vnew #-}   vnew init = runST (do@@ -42,15 +105,341 @@   {-# INLINE unsafeSlice #-}   unsafeSlice (Vector i _ arr#) j n = Vector (i+j) n arr# -  {-# INLINE unsafeIndex #-}-  unsafeIndex (Vector (I# i#) _ arr#) (I# j#) f-    = case indexArray# arr# (i# +# j#) of (# x #) -> f x+  {-# INLINE unsafeIndexM #-}+  unsafeIndexM (Vector (I# i#) _ arr#) (I# j#)+    = case indexArray# arr# (i# +# j#) of (# x #) -> return x  instance Eq a => Eq (Vector a) where   {-# INLINE (==) #-}-  (==) = eq+  (==) = IV.eq  instance Ord a => Ord (Vector a) where   {-# INLINE compare #-}-  compare = cmp+  compare = IV.cmp++-- Length+-- ------++length :: Vector a -> Int+{-# INLINE length #-}+length = IV.length++null :: Vector a -> Bool+{-# INLINE null #-}+null = IV.null++-- Construction+-- ------------++-- | Empty vector+empty :: Vector a+{-# INLINE empty #-}+empty = IV.empty++-- | Vector with exaclty one element+singleton :: a -> Vector a+{-# INLINE singleton #-}+singleton = IV.singleton++-- | Vector of the given length with the given value in each position+replicate :: Int -> a -> Vector a+{-# INLINE replicate #-}+replicate = IV.replicate++-- | Prepend an element+cons :: a -> Vector a -> Vector a+{-# INLINE cons #-}+cons = IV.cons++-- | Append an element+snoc :: Vector a -> a -> Vector a+{-# INLINE snoc #-}+snoc = IV.snoc++infixr 5 +++-- | Concatenate two vectors+(++) :: Vector a -> Vector a -> Vector a+{-# INLINE (++) #-}+(++) = (IV.++)++-- | Create a copy of a vector. Useful when dealing with slices.+copy :: Vector a -> Vector a+{-# INLINE copy #-}+copy = IV.copy++-- Accessing individual elements+-- -----------------------------++-- | Indexing+(!) :: Vector a -> Int -> a+{-# INLINE (!) #-}+(!) = (IV.!)++-- | First element+head :: Vector a -> a+{-# INLINE head #-}+head = IV.head++-- | Last element+last :: Vector a -> a+{-# INLINE last #-}+last = IV.last++-- | Monadic indexing which can be strict in the vector while remaining lazy in+-- the element+indexM :: Monad m => Vector a -> Int -> m a+{-# INLINE indexM #-}+indexM = IV.indexM++headM :: Monad m => Vector a -> m a+{-# INLINE headM #-}+headM = IV.headM++lastM :: Monad m => Vector a -> m a+{-# INLINE lastM #-}+lastM = IV.lastM++-- Subarrays+-- ---------++-- | Yield a part of the vector without copying it. Safer version of+-- 'unsafeSlice'.+slice :: Vector a -> Int   -- ^ starting index+                  -> Int   -- ^ length+                  -> Vector a+{-# INLINE slice #-}+slice = IV.slice++-- | Yield all but the last element without copying.+init :: Vector a -> Vector a+{-# INLINE init #-}+init = IV.init++-- | All but the first element (without copying).+tail :: Vector a -> Vector a+{-# INLINE tail #-}+tail = IV.tail++-- | Yield the first @n@ elements without copying.+take :: Int -> Vector a -> Vector a+{-# INLINE take #-}+take = IV.take++-- | Yield all but the first @n@ elements without copying.+drop :: Int -> Vector a -> Vector a+{-# INLINE drop #-}+drop = IV.drop++-- Permutations+-- ------------++accum :: (a -> b -> a) -> Vector a -> [(Int,b)] -> Vector a+{-# INLINE accum #-}+accum = IV.accum++(//) :: Vector a -> [(Int, a)] -> Vector a+{-# INLINE (//) #-}+(//) = (IV.//)++update :: Vector a -> Vector (Int, a) -> Vector a+{-# INLINE update #-}+update = IV.update++backpermute :: Vector a -> Vector Int -> Vector a+{-# INLINE backpermute #-}+backpermute = IV.backpermute++reverse :: Vector a -> Vector a+{-# INLINE reverse #-}+reverse = IV.reverse++-- Mapping+-- -------++-- | Map a function over a vector+map :: (a -> b) -> Vector a -> Vector b+{-# INLINE map #-}+map = IV.map++concatMap :: (a -> Vector b) -> Vector a -> Vector b+{-# INLINE concatMap #-}+concatMap = IV.concatMap++-- Zipping/unzipping+-- -----------------++-- | Zip two vectors with the given function.+zipWith :: (a -> b -> c) -> Vector a -> Vector b -> Vector c+{-# INLINE zipWith #-}+zipWith = IV.zipWith++-- | Zip three vectors with the given function.+zipWith3 :: (a -> b -> c -> d) -> Vector a -> Vector b -> Vector c -> Vector d+{-# INLINE zipWith3 #-}+zipWith3 = IV.zipWith3++zip :: Vector a -> Vector b -> Vector (a, b)+{-# INLINE zip #-}+zip = IV.zip++zip3 :: Vector a -> Vector b -> Vector c -> Vector (a, b, c)+{-# INLINE zip3 #-}+zip3 = IV.zip3++unzip :: Vector (a, b) -> (Vector a, Vector b)+{-# INLINE unzip #-}+unzip = IV.unzip++unzip3 :: Vector (a, b, c) -> (Vector a, Vector b, Vector c)+{-# INLINE unzip3 #-}+unzip3 = IV.unzip3++-- Filtering+-- ---------++-- | Drop elements which do not satisfy the predicate+filter :: (a -> Bool) -> Vector a -> Vector a+{-# INLINE filter #-}+filter = IV.filter++-- | Yield the longest prefix of elements satisfying the predicate.+takeWhile :: (a -> Bool) -> Vector a -> Vector a+{-# INLINE takeWhile #-}+takeWhile = IV.takeWhile++-- | Drop the longest prefix of elements that satisfy the predicate.+dropWhile :: (a -> Bool) -> Vector a -> Vector a+{-# INLINE dropWhile #-}+dropWhile = IV.dropWhile++-- Searching+-- ---------++infix 4 `elem`+-- | Check whether the vector contains an element+elem :: Eq a => a -> Vector a -> Bool+{-# INLINE elem #-}+elem = IV.elem++infix 4 `notElem`+-- | Inverse of `elem`+notElem :: Eq a => a -> Vector a -> Bool+{-# INLINE notElem #-}+notElem = IV.notElem++-- | Yield 'Just' the first element matching the predicate or 'Nothing' if no+-- such element exists.+find :: (a -> Bool) -> Vector a -> Maybe a+{-# INLINE find #-}+find = IV.find++-- | Yield 'Just' the index of the first element matching the predicate or+-- 'Nothing' if no such element exists.+findIndex :: (a -> Bool) -> Vector a -> Maybe Int+{-# INLINE findIndex #-}+findIndex = IV.findIndex++-- Folding+-- -------++-- | Left fold+foldl :: (a -> b -> a) -> a -> Vector b -> a+{-# INLINE foldl #-}+foldl = IV.foldl++-- | Lefgt fold on non-empty vectors+foldl1 :: (a -> a -> a) -> Vector a -> a+{-# INLINE foldl1 #-}+foldl1 = IV.foldl1++-- | Left fold with strict accumulator+foldl' :: (a -> b -> a) -> a -> Vector b -> a+{-# INLINE foldl' #-}+foldl' = IV.foldl'++-- | Left fold on non-empty vectors with strict accumulator+foldl1' :: (a -> a -> a) -> Vector a -> a+{-# INLINE foldl1' #-}+foldl1' = IV.foldl1'++-- | Right fold+foldr :: (a -> b -> b) -> b -> Vector a -> b+{-# INLINE foldr #-}+foldr = IV.foldr++-- | Right fold on non-empty vectors+foldr1 :: (a -> a -> a) -> Vector a -> a+{-# INLINE foldr1 #-}+foldr1 = IV.foldr1++-- Specialised folds+-- -----------------++and :: Vector Bool -> Bool+{-# INLINE and #-}+and = IV.and++or :: Vector Bool -> Bool+{-# INLINE or #-}+or = IV.or++sum :: Num a => Vector a -> a+{-# INLINE sum #-}+sum = IV.sum++product :: Num a => Vector a -> a+{-# INLINE product #-}+product = IV.product++maximum :: Ord a => Vector a -> a+{-# INLINE maximum #-}+maximum = IV.maximum++minimum :: Ord a => Vector a -> a+{-# INLINE minimum #-}+minimum = IV.minimum++-- Unfolding+-- ---------++unfoldr :: (b -> Maybe (a, b)) -> b -> Vector a+{-# INLINE unfoldr #-}+unfoldr = IV.unfoldr++-- Scans+-- -----++-- | Prefix scan+prescanl :: (a -> b -> a) -> a -> Vector b -> Vector a+{-# INLINE prescanl #-}+prescanl = IV.prescanl++-- | Prefix scan with strict accumulator+prescanl' :: (a -> b -> a) -> a -> Vector b -> Vector a+{-# INLINE prescanl' #-}+prescanl' = IV.prescanl'++-- Enumeration+-- -----------++enumFromTo :: Enum a => a -> a -> Vector a+{-# INLINE enumFromTo #-}+enumFromTo = IV.enumFromTo++enumFromThenTo :: Enum a => a -> a -> a -> Vector a+{-# INLINE enumFromThenTo #-}+enumFromThenTo = IV.enumFromThenTo++-- Conversion to/from lists+-- ------------------------++-- | Convert a vector to a list+toList :: Vector a -> [a]+{-# INLINE toList #-}+toList = IV.toList++-- | Convert a list to a vector+fromList :: [a] -> Vector a+{-# INLINE fromList #-}+fromList = IV.fromList 
Data/Vector/Fusion/Stream.hs view
@@ -16,7 +16,7 @@  module Data.Vector.Fusion.Stream (   -- * Types-  Step(..), Stream, MStream, Id(..),+  Step(..), Stream, MStream,    -- * Size hints   size, sized,@@ -33,8 +33,11 @@   -- * Substreams   extract, init, tail, take, drop, -  -- * Mapping and zipping-  map, zipWith,+  -- * Mapping+  map, concatMap,+  +  -- * Zipping+  zipWith, zipWith3,    -- * Filtering   filter, takeWhile, dropWhile,@@ -45,8 +48,11 @@   -- * Folding   foldl, foldl1, foldl', foldl1', foldr, foldr1, +  -- * Specialised folds+  and, or,+   -- * Unfolding-  unfold,+  unfoldr,    -- * Scans   prescanl, prescanl',@@ -59,6 +65,7 @@ ) where  import Data.Vector.Fusion.Stream.Size+import Data.Vector.Fusion.Util import Data.Vector.Fusion.Stream.Monadic ( Step(..) ) import qualified Data.Vector.Fusion.Stream.Monadic as M @@ -66,23 +73,14 @@                         replicate, (++),                         head, last, (!!),                         init, tail, take, drop,-                        map, zipWith,+                        map, concatMap,+                        zipWith, zipWith3,                         filter, takeWhile, dropWhile,                         elem, notElem,                         foldl, foldl1, foldr, foldr1,+                        and, or,                         mapM_ ) ---- | Identity monad-newtype Id a = Id { unId :: a }--instance Functor Id where-  fmap f (Id x) = Id (f x)--instance Monad Id where-  return     = Id-  Id x >>= f = f x- -- | The type of pure streams  type Stream = M.Stream Id @@ -199,7 +197,7 @@ {-# INLINE drop #-} drop = M.drop --- Mapping/zipping+-- Mapping -- ---------------  -- | Map a function over a 'Stream'@@ -207,11 +205,23 @@ {-# INLINE map #-} map = M.map +concatMap :: (a -> Stream b) -> Stream a -> Stream b+{-# INLINE concatMap #-}+concatMap = M.concatMap++-- Zipping+-- -------+ -- | Zip two 'Stream's with the given function zipWith :: (a -> b -> c) -> Stream a -> Stream b -> Stream c {-# INLINE zipWith #-} zipWith = M.zipWith +-- | Zip three 'Stream's with the given function+zipWith3 :: (a -> b -> c -> d) -> Stream a -> Stream b -> Stream c -> Stream d+{-# INLINE zipWith3 #-}+zipWith3 = M.zipWith3+ -- Filtering -- --------- @@ -290,13 +300,24 @@ {-# INLINE foldr1 #-} foldr1 f = unId . M.foldr1 f +-- Specialised folds+-- -----------------++and :: Stream Bool -> Bool+{-# INLINE and #-}+and = unId . M.and++or :: Stream Bool -> Bool+{-# INLINE or #-}+or = unId . M.or+ -- Unfolding -- ---------  -- | Unfold-unfold :: (s -> Maybe (a, s)) -> s -> Stream a-{-# INLINE unfold #-}-unfold = M.unfold+unfoldr :: (s -> Maybe (a, s)) -> s -> Stream a+{-# INLINE unfoldr #-}+unfoldr = M.unfoldr  -- Scans -- -----
Data/Vector/Fusion/Stream/Monadic.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE ExistentialQuantification #-}+{-# LANGUAGE ExistentialQuantification, Rank2Types #-}  -- | -- Module      : Data.Vector.Fusion.Stream.Monadic@@ -32,8 +32,11 @@   -- * Substreams   extract, init, tail, take, drop, -  -- * Mapping and zipping-  map, mapM, mapM_, zipWith, zipWithM,+  -- * Mapping+  map, mapM, mapM_, trans, concatMap,+  +  -- * Zipping+  zipWith, zipWithM, zipWith3, zipWith3M,    -- * Filtering   filter, filterM, takeWhile, takeWhileM, dropWhile, dropWhileM,@@ -46,8 +49,11 @@   foldl', foldlM', foldl1', foldl1M',   foldr, foldrM, foldr1, foldr1M, +  -- * Specialised folds+  and, or, concatMapM,+   -- * Unfolding-  unfold, unfoldM,+  unfoldr, unfoldrM,    -- * Scans   prescanl, prescanlM, prescanl', prescanlM',@@ -63,10 +69,12 @@                         replicate, (++),                         head, last, (!!),                         init, tail, take, drop,-                        map, mapM, mapM_, zipWith,+                        map, mapM, mapM_, concatMap,+                        zipWith, zipWith3,                         filter, takeWhile, dropWhile,                         elem, notElem,-                        foldl, foldl1, foldr, foldr1 )+                        foldl, foldl1, foldr, foldr1,+                        and, or ) import qualified Prelude  -- | Result of taking a single step in a stream@@ -193,7 +201,17 @@ -- | Element at the given position (!!) :: Monad m => Stream m a -> Int -> m a {-# INLINE (!!) #-}-s !! i = head (drop i s)+Stream step s _ !! i | i < 0     = errorNegativeIndex "!!"+                     | otherwise = loop s i+  where+    loop s i = i `seq`+               do+                 r <- step s+                 case r of+                   Yield x s' | i == 0    -> return x+                              | otherwise -> loop s' (i-1)+                   Skip    s'             -> loop s' i+                   Done                   -> errorIndexOutOfRange "!!"  -- Substreams -- ----------@@ -215,7 +233,7 @@                            case r of                              Yield x s' -> Skip (Just x,  s')                              Skip    s' -> Skip (Nothing, s')-                             Done       -> Done  -- FIXME: should be an error+                             Done       -> errorEmptyStream "init"                          ) (step s)      step' (Just x,  s) = liftM (\r -> @@ -235,7 +253,7 @@                         case r of                           Yield x s' -> Skip (Right s')                           Skip    s' -> Skip (Left  s')-                          Done       -> Done    -- FIXME: should be error?+                          Done       -> errorEmptyStream "tail"                       ) (step s)      step' (Right s) = liftM (\r ->@@ -281,8 +299,8 @@                            ) (step s)                       --- Mapping/zipping--- ---------------+-- Mapping+-- -------  instance Monad m => Functor (Stream m) where   {-# INLINE fmap #-}@@ -318,6 +336,15 @@                     Skip    s' -> mapM_go s'                     Done       -> return () +-- | Transform a 'Stream' to use a different monad+trans :: (Monad m, Monad m') => (forall a. m a -> m' a)+                             -> Stream m a -> Stream m' a+{-# INLINE_STREAM trans #-}+trans f (Stream step s n) = Stream (f . step) s n++-- Zipping+-- -------+ -- | Zip two 'Stream's with the given function zipWith :: Monad m => (a -> b -> c) -> Stream m a -> Stream m b -> Stream m c {-# INLINE zipWith #-}@@ -347,6 +374,39 @@                                  Skip    sb' -> return $ Skip (sa, sb', Just x)                                  Done        -> return $ Done +-- | Zip three 'Stream's with the given function+zipWith3 :: Monad m => (a -> b -> c -> d) -> Stream m a -> Stream m b -> Stream m c -> Stream m d+{-# INLINE zipWith3 #-}+zipWith3 f = zipWith3M (\a b c -> return (f a b c))++-- | Zip three 'Stream's with the given monadic function+zipWith3M :: Monad m => (a -> b -> c -> m d) -> Stream m a -> Stream m b -> Stream m c -> Stream m d+{-# INLINE_STREAM zipWith3M #-}+zipWith3M f (Stream stepa sa na) (Stream stepb sb nb) (Stream stepc sc nc)+  = Stream step (sa, sb, sc, Nothing) (smaller na (smaller nb nc))+  where+    {-# INLINE step #-}+    step (sa, sb, sc, Nothing) = do+        r <- stepa sa+        return $ case r of+            Yield x sa' -> Skip (sa', sb, sc, Just (x, Nothing))+            Skip    sa' -> Skip (sa', sb, sc, Nothing)+            Done        -> Done++    step (sa, sb, sc, Just (x, Nothing)) = do+        r <- stepb sb+        return $ case r of+            Yield y sb' -> Skip (sa, sb', sc, Just (x, Just y))+            Skip    sb' -> Skip (sa, sb', sc, Just (x, Nothing))+            Done        -> Done++    step (sa, sb, sc, Just (x, Just y)) = do+        r <- stepc sc+        case r of+            Yield z sc' -> f x y z >>= (\res -> return $ Yield res (sa, sb, sc', Nothing))+            Skip    sc' -> return $ Skip (sa, sb, sc', Just (x, Just y))+            Done        -> return $ Done+ -- Filtering -- --------- @@ -614,18 +674,68 @@                           Skip    s' -> foldr1M_go1 x s'                           Done       -> return x +-- Specialised folds+-- -----------------++and :: Monad m => Stream m Bool -> m Bool+{-# INLINE_STREAM and #-}+and (Stream step s _) = and_go s+  where+    and_go s = do+                 r <- step s+                 case r of+                   Yield False _  -> return False+                   Yield True  s' -> and_go s'+                   Skip        s' -> and_go s'+                   Done           -> return True++or :: Monad m => Stream m Bool -> m Bool+{-# INLINE_STREAM or #-}+or (Stream step s _) = or_go s+  where+    or_go s = do+                r <- step s+                case r of+                  Yield False s' -> or_go s'+                  Yield True  _  -> return True+                  Skip        s' -> or_go s'+                  Done           -> return False++concatMap :: Monad m => (a -> Stream m b) -> Stream m a -> Stream m b+{-# INLINE concatMap #-}+concatMap f = concatMapM (return . f)++concatMapM :: Monad m => (a -> m (Stream m b)) -> Stream m a -> Stream m b+{-# INLINE_STREAM concatMapM #-}+concatMapM f (Stream step s _) = Stream concatMap_go (Left s) Unknown+  where+    concatMap_go (Left s) = do+        r <- step s+        case r of+            Yield a s' -> do+                b_stream <- f a+                return $ Skip (Right (b_stream, s'))+            Skip    s' -> return $ Skip (Left s')+            Done       -> return Done+    concatMap_go (Right (Stream inner_step inner_s sz, s)) = do+        r <- inner_step inner_s+        case r of+            Yield b inner_s' -> return $ Yield b (Right (Stream inner_step inner_s' sz, s))+            Skip    inner_s' -> return $ Skip (Right (Stream inner_step inner_s' sz, s))+            Done             -> return $ Skip (Left s)+ -- Unfolding -- ---------  -- | Unfold-unfold :: Monad m => (s -> Maybe (a, s)) -> s -> Stream m a-{-# INLINE_STREAM unfold #-}-unfold f = unfoldM (return . f)+unfoldr :: Monad m => (s -> Maybe (a, s)) -> s -> Stream m a+{-# INLINE_STREAM unfoldr #-}+unfoldr f = unfoldrM (return . f)  -- | Unfold with a monadic function-unfoldM :: Monad m => (s -> m (Maybe (a, s))) -> s -> Stream m a-{-# INLINE_STREAM unfoldM #-}-unfoldM f s = Stream step s Unknown+unfoldrM :: Monad m => (s -> m (Maybe (a, s))) -> s -> Stream m a+{-# INLINE_STREAM unfoldrM #-}+unfoldrM f s = Stream step s Unknown   where     {-# INLINE step #-}     step s = liftM (\r ->@@ -695,7 +805,16 @@     step []     = return Done  +streamError :: String -> String -> a+streamError fn msg = error $ "Data.Vector.Fusion.Stream.Monadic."+                             Prelude.++ fn Prelude.++ ": " Prelude.++ msg+ errorEmptyStream :: String -> a-errorEmptyStream s = error $ "Data.Vector.Fusion.Stream.Monadic."-                        Prelude.++ s Prelude.++ ": empty stream"+errorEmptyStream fn = streamError fn "empty stream"++errorNegativeIndex :: String -> a+errorNegativeIndex fn = streamError fn "negative index"++errorIndexOutOfRange :: String -> a+errorIndexOutOfRange fn = streamError fn "index out of range" 
+ Data/Vector/Fusion/Util.hs view
@@ -0,0 +1,35 @@+-- |+-- Module      : Data.Vector.Fusion.Util+-- Copyright   : (c) Roman Leshchinskiy 2009+-- License     : BSD-style+--+-- Maintainer  : Roman Leshchinskiy <rl@cse.unsw.edu.au>+-- Stability   : experimental+-- Portability : portable+-- +-- Fusion-related utility types+--++module Data.Vector.Fusion.Util ( Id(..), Box(..) )+where++-- | Identity monad+newtype Id a = Id { unId :: a }++instance Functor Id where+  fmap f (Id x) = Id (f x)++instance Monad Id where+  return     = Id+  Id x >>= f = f x++-- | Box monad+data Box a = Box { unBox :: a }++instance Functor Box where+  fmap f (Box x) = Box (f x)++instance Monad Box where+  return      = Box+  Box x >>= f = f x+
Data/Vector/IVector.hs view
@@ -19,38 +19,50 @@   IVector,    -- * Length information-  length,+  length, null,    -- * Construction-  empty, singleton, cons, snoc, replicate, (++),+  empty, singleton, cons, snoc, replicate, (++), copy,    -- * Accessing individual elements-  (!), head, last,+  (!), head, last, indexM, headM, lastM,    -- * Subvectors-  slice, extract, takeSlice, take, dropSlice, drop,+  slice, init, tail, take, drop,    -- * Permutations-  (//), update, bpermute,+  accum, (//), update, backpermute, reverse, -  -- * Mapping and zipping-  map, zipWith, zip,+  -- * Mapping+  map, concatMap, +  -- * Zipping and unzipping+  zipWith, zipWith3, zip, zip3, unzip, unzip3,+   -- * Comparisons   eq, cmp,    -- * Filtering-  filter, takeWhileSlice, takeWhile, dropWhileSlice, dropWhile,+  filter, takeWhile, dropWhile,    -- * Searching   elem, notElem, find, findIndex,    -- * Folding   foldl, foldl1, foldl', foldl1', foldr, foldr1,+ +  -- * Specialised folds+  and, or, sum, product, maximum, minimum, +  -- * Unfolding+  unfoldr,+   -- * Scans   prescanl, prescanl', +  -- * Enumeration+  enumFromTo, enumFromThenTo,+   -- * Conversion to/from lists   toList, fromList, @@ -61,7 +73,7 @@   new,    -- * Unsafe functions-  unsafeSlice, unsafeIndex,+  unsafeSlice, unsafeIndexM,    -- * Utility functions   vlength, vnew@@ -77,17 +89,21 @@ 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,+import Prelude hiding ( length, null,                         replicate, (++),                         head, last,-                        init, tail, take, drop,-                        map, zipWith, zip,+                        init, tail, take, drop, reverse,+                        map, concatMap,+                        zipWith, zipWith3, zip, zip3, unzip, unzip3,                         filter, takeWhile, dropWhile,                         elem, notElem,-                        foldl, foldl1, foldr, foldr1 )+                        foldl, foldl1, foldr, foldr1,+                        and, or, sum, product, maximum, minimum,+                        enumFromTo, enumFromThenTo )  -- | Class of immutable vectors. --@@ -101,26 +117,28 @@   -- | Yield a part of the vector without copying it. No range checks!   unsafeSlice  :: v a -> Int -> Int -> v a -  -- | Apply the given function to the element at the given position. This-  -- interface prevents us from being too lazy. Suppose we had+  -- | Yield the element at the given position in a monad. The monad allows us+  -- to be strict in the vector if we want. Suppose we had   ---  -- > unsafeIndex' :: v a -> Int -> a+  -- > unsafeIndex :: v a -> Int -> a   --   -- instead. Now, if we wanted to copy a vector, we'd do something like   ---  -- > copy mv v ... = ... unsafeWrite mv i (unsafeIndex' v i) ...+  -- > copy mv v ... = ... unsafeWrite mv i (unsafeIndex v i) ...   --   -- For lazy vectors, the indexing would not be evaluated which means that we   -- would retain a reference to the original vector in each element we write.-  -- This would be bad!+  -- This is not what we want!   ---  -- With 'unsafeIndex', we can do+  -- With 'unsafeIndexM', we can do   ---  -- > copy mv v ... = ... unsafeIndex v i (unsafeWrite mv i) ...+  -- > copy mv v ... = ... case unsafeIndexM v i of+  --                         Box x -> unsafeWrite mv i x ...   ---  -- which does not have this problem.+  -- which does not have this problem because indexing (but not the returned+  -- element!) is evaluated immediately.   ---  unsafeIndex  :: v a -> Int -> (a -> b) -> b+  unsafeIndexM  :: Monad m => v a -> Int -> m a  -- Fusion -- ------@@ -141,12 +159,12 @@ -- | Convert a vector to a 'Stream' stream :: IVector v a => v a -> Stream a {-# INLINE_STREAM stream #-}-stream v = v `seq` (Stream.unfold get 0 `Stream.sized` Exact n)+stream v = v `seq` (Stream.unfoldr get 0 `Stream.sized` Exact n)   where     n = length v      {-# INLINE get #-}-    get i | i < n     = unsafeIndex v i $ \x -> Just (x, i+1)+    get i | i < n     = case unsafeIndexM v i of Box x -> Just (x, i+1)           | otherwise = Nothing  -- | Create a vector from a 'Stream'@@ -201,6 +219,17 @@    #-} +null :: IVector v a => v a -> Bool+{-# INLINE_STREAM null #-}+null v = vlength v == 0++{-# RULES++"null/unstream [IVector]" forall v s.+  null (new' v (New.unstream s)) = Stream.null s++  #-}+ -- Construction -- ------------ @@ -235,6 +264,18 @@ {-# INLINE (++) #-} v ++ w = unstream (stream v Stream.++ stream w) +-- | Create a copy of a vector. Useful when dealing with slices.+copy :: IVector v a => v a -> v a+{-# INLINE_STREAM copy #-}+copy = unstream . stream++{-# RULES++"copy/unstream [IVector]" forall v s.+  copy (new' v (New.unstream s)) = new' v (New.unstream s)++ #-}+ -- Accessing individual elements -- ----------------------------- @@ -242,7 +283,7 @@ (!) :: IVector v a => v a -> Int -> a {-# INLINE_STREAM (!) #-} v ! i = assert (i >= 0 && i < length v)-      $ unsafeIndex v i id+      $ unId (unsafeIndexM v i)  -- | First element head :: IVector v a => v a -> a@@ -267,6 +308,34 @@   #-} +-- | Monadic indexing which can be strict in the vector while remaining lazy in+-- the element.+indexM :: (IVector v a, Monad m) => v a -> Int -> m a+{-# INLINE_STREAM indexM #-}+indexM v i = assert (i >= 0 && i < length v)+           $ unsafeIndexM v i++headM :: (IVector v a, Monad m) => v a -> m a+{-# INLINE_STREAM headM #-}+headM v = indexM v 0++lastM :: (IVector v a, Monad m) => v a -> m a+{-# INLINE_STREAM lastM #-}+lastM v = indexM v (length v - 1)++{-# RULES++"indexM/unstream [IVector]" forall v i s.+  indexM (new' v (New.unstream s)) i = return (s Stream.!! i)++"headM/unstream [IVector]" forall v s.+  headM (new' v (New.unstream s)) = return (Stream.head s)++"lastM/unstream [IVector]" forall v s.+  lastM (new' v (New.unstream s)) = return (Stream.last s)++ #-}+ -- Subarrays -- --------- @@ -281,43 +350,56 @@ slice v i n = assert (i >= 0 && n >= 0  && i+n <= length v)             $ unsafeSlice v i n --- | Copy @n@ elements starting at the given position to a new vector.-extract :: IVector v a => v a -> Int  -- ^ starting index-                              -> Int  -- ^ length-                              -> v a-{-# INLINE extract #-}-extract v i n = unstream (Stream.extract (stream v) i n)+-- | Yield all but the last element without copying.+init :: IVector v a => v a -> v a+{-# INLINE_STREAM init #-}+init v = slice v 0 (length v - 1) --- | Yield the first @n@ elements without copying.-takeSlice :: IVector v a => Int -> v a -> v a-{-# INLINE takeSlice #-}-takeSlice n v = slice v 0 n+-- | All but the first element (without copying).+tail :: IVector v a => v a -> v a+{-# INLINE_STREAM tail #-}+tail v = slice v 1 (length v - 1) --- | Copy the first @n@ elements to a new vector.+-- | Yield the first @n@ elements without copying. take :: IVector v a => Int -> v a -> v a-{-# INLINE take #-}-take n = unstream . Stream.take n . stream+{-# INLINE_STREAM take #-}+take n v = slice v 0 (min n' (length v))+  where n' = max n 0  -- | Yield all but the first @n@ elements without copying.-dropSlice :: IVector v a => Int -> v a -> v a-{-# INLINE dropSlice #-}-dropSlice n v = slice v n (length v - n)---- | Copy all but the first @n@ elements to a new vectors. drop :: IVector v a => Int -> v a -> v a-{-# INLINE drop #-}-drop n = unstream . Stream.drop n . stream+{-# INLINE_STREAM drop #-}+drop n v = slice v (min n' len) (max 0 (len - n'))+  where n' = max n 0+        len = length v  {-# RULES -"slice/unstream [IVector]" forall v i n s.-  slice (new' v (New.unstream s)) i n = extract (new' v (New.unstream s)) i n+"slice/new [IVector]" forall v p i n.+  slice (new' v p) i n = new' v (New.slice p i n) +"init/new [IVector]" forall v p.+  init (new' v p) = new' v (New.init p)++"tail/new [IVector]" forall v p.+  tail (new' v p) = new' v (New.tail p)++"take/new [IVector]" forall n v p.+  take n (new' v p) = new' v (New.take n p)++"drop/new [IVector]" forall n v p.+  drop n (new' v p) = new' v (New.drop n p)+   #-}  -- Permutations -- ------------ +accum :: IVector v a => (a -> b -> a) -> v a -> [(Int,b)] -> v a+{-# INLINE accum #-}+accum f v us = new (New.accum f (New.unstream (stream v))+                                (Stream.fromList us))+ (//) :: IVector v a => v a -> [(Int, a)] -> v a {-# INLINE (//) #-} v // us = new (New.update (New.unstream (stream v))@@ -327,13 +409,26 @@ {-# INLINE update #-} update v w = new (New.update (New.unstream (stream v)) (stream w)) -bpermute :: (IVector v a, IVector v Int) => v a -> v Int -> v a-{-# INLINE bpermute #-}-bpermute v is = v `seq` map (v!) is+-- This somewhat non-intuitive definition ensures that the resulting vector+-- does not retain references to the original one even if it is lazy in its+-- elements. This would not be the case if we simply used+--+-- backpermute v is = map (v!) is+backpermute :: (IVector v a, IVector v Int) => v a -> v Int -> v a+{-# INLINE backpermute #-}+backpermute v is = unstream+                 . MStream.trans (Id . unBox)+                 . MStream.mapM (indexM v)+                 . MStream.trans (Box . unId)+                 $ stream is --- Mapping/zipping--- ---------------+reverse :: (IVector v a) => v a -> v a+{-# INLINE reverse #-}+reverse = new . New.reverse . New.unstream . stream +-- Mapping+-- -------+ -- | Map a function over a vector map :: (IVector v a, IVector v b) => (a -> b) -> v a -> v b {-# INLINE map #-}@@ -349,15 +444,39 @@   #-} +concatMap :: (IVector v a, IVector v b) => (a -> v b) -> v a -> v b+{-# INLINE concatMap #-}+concatMap f = unstream . Stream.concatMap (stream . f) . stream++-- Zipping/unzipping+-- -----------------+ -- | Zip two vectors with the given function. zipWith :: (IVector v a, IVector v b, IVector v c) => (a -> b -> c) -> v a -> v b -> v c {-# INLINE zipWith #-} zipWith f xs ys = unstream (Stream.zipWith f (stream xs) (stream ys)) +-- | Zip three vectors with the given function.+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+{-# INLINE zipWith3 #-}+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) {-# INLINE zip #-} 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)+{-# INLINE zip3 #-}+zip3 = zipWith3 (,,)++unzip :: (IVector v a, IVector v b, IVector v (a,b)) => v (a, b) -> (v a, v b)+{-# INLINE unzip #-}+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)+{-# INLINE unzip3 #-}+unzip3 xs = (map (\(a, b, c) -> a) xs, map (\(a, b, c) -> b) xs, map (\(a, b, c) -> c) xs)+ -- Comparisons -- ----------- @@ -377,44 +496,16 @@ {-# INLINE filter #-} filter f = unstream . inplace (MStream.filter f) . stream --- | Yield the longest prefix of elements satisfying the predicate without--- copying.-takeWhileSlice :: IVector v a => (a -> Bool) -> v a -> v a-{-# INLINE_STREAM takeWhileSlice #-}-takeWhileSlice f v = case findIndex (not . f) v of-                       Just n  -> takeSlice n v-                       Nothing -> v---- | Copy the longest prefix of elements satisfying the predicate to a new--- vector+-- | Yield the longest prefix of elements satisfying the predicate. takeWhile :: IVector v a => (a -> Bool) -> v a -> v a {-# INLINE takeWhile #-} takeWhile f = unstream . Stream.takeWhile f . stream --- | Drop the longest prefix of elements that satisfy the predicate without--- copying-dropWhileSlice :: IVector v a => (a -> Bool) -> v a -> v a-{-# INLINE_STREAM dropWhileSlice #-}-dropWhileSlice f v = case findIndex (not . f) v of-                       Just n  -> dropSlice n v-                       Nothing -> v---- | Drop the longest prefix of elements that satisfy the predicate and copy--- the rest to a new vector.+-- | Drop the longest prefix of elements that satisfy the predicate. dropWhile :: IVector v a => (a -> Bool) -> v a -> v a {-# INLINE dropWhile #-} dropWhile f = unstream . Stream.dropWhile f . stream -{-# RULES--"takeWhileSlice/unstream" forall v f s.-  takeWhileSlice f (new' v (New.unstream s)) = takeWhile f (new' v (New.unstream s))--"dropWhileSlice/unstream" forall v f s.-  dropWhileSlice f (new' v (New.unstream s)) = dropWhile f (new' v (New.unstream s))-- #-}- -- Searching -- --------- @@ -475,6 +566,40 @@ {-# INLINE foldr1 #-} foldr1 f = Stream.foldr1 f . stream +-- Specialised folds+-- -----------------++and :: IVector v Bool => v Bool -> Bool+{-# INLINE and #-}+and = Stream.and . stream++or :: IVector v Bool => v Bool -> Bool+{-# INLINE or #-}+or = Stream.or . stream++sum :: (IVector v a, Num a) => v a -> a+{-# INLINE sum #-}+sum = Stream.foldl' (+) 0 . stream++product :: (IVector v a, Num a) => v a -> a+{-# INLINE product #-}+product = Stream.foldl' (*) 1 . stream++maximum :: (IVector v a, Ord a) => v a -> a+{-# INLINE maximum #-}+maximum = Stream.foldl1' max . stream++minimum :: (IVector v a, Ord a) => v a -> a+{-# INLINE minimum #-}+minimum = Stream.foldl1' min . stream++-- Unfolding+-- ---------++unfoldr :: IVector v a => (b -> Maybe (a, b)) -> b -> v a+{-# INLINE unfoldr #-}+unfoldr f = unstream . Stream.unfoldr f+ -- Scans -- ----- @@ -508,6 +633,27 @@   #-} ++-- Enumeration+-- -----------++enumFromTo :: (IVector v a, Enum a) => a -> a -> v a+{-# INLINE enumFromTo #-}+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+{-# INLINE enumFromThenTo #-}+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  -- | Convert a vector to a list toList :: IVector v a => v a -> [a]
Data/Vector/MVector.hs view
@@ -18,7 +18,7 @@    slice, new, newWith, read, write, copy, grow,   unstream, transform,-  update, reverse+  accum, update, reverse ) where  import qualified Data.Vector.Fusion.Stream      as Stream@@ -169,7 +169,7 @@  mstream :: MVector v m a => v a -> MStream m a {-# INLINE mstream #-}-mstream v = v `seq` (MStream.unfoldM get 0 `MStream.sized` Exact n)+mstream v = v `seq` (MStream.unfoldrM get 0 `MStream.sized` Exact n)   where     n = length v @@ -229,12 +229,18 @@                                  . double2Int                                  $ int2Double (length v) * gROWTH_FACTOR +accum :: MVector v m a => (a -> b -> a) -> v a -> Stream (Int, b) -> m ()+{-# INLINE accum #-}+accum f v s = Stream.mapM_ upd s+  where+    {-# INLINE upd #-}+    upd (i,b) = do+                  a <- read v i+                  write v i (f a b)+ update :: MVector v m a => v a -> Stream (Int, a) -> m () {-# INLINE update #-}-update v s = Stream.mapM_ put s-  where-    {-# INLINE put #-}-    put (i, x) = write v i x+update = accum (const id)  reverse :: MVector v m a => v a -> m () {-# INLINE reverse #-}@@ -245,5 +251,6 @@                                  y <- unsafeRead v j                                  unsafeWrite v i y                                  unsafeWrite v j x+                                 reverse_loop (i + 1) (j - 1)     reverse_loop _ _ = return () 
Data/Vector/MVector/New.hs view
@@ -3,11 +3,12 @@ #include "phases.h"  module Data.Vector.MVector.New (-  New(..), run, unstream, transform, update, reverse+  New(..), run, unstream, transform, accum, update, reverse,+  slice, init, tail, take, drop ) where  import qualified Data.Vector.MVector as MVector-import           Data.Vector.MVector ( MVector )+import           Data.Vector.MVector ( MVector, MVectorPure )  import           Data.Vector.Fusion.Stream ( Stream, MStream ) import qualified Data.Vector.Fusion.Stream as Stream@@ -15,7 +16,7 @@ import qualified Data.Vector.Fusion.Stream.Monadic as MStream  import Control.Monad  ( liftM )-import Prelude hiding ( reverse, map, filter )+import Prelude hiding ( init, tail, take, drop, reverse, map, filter )  newtype New a = New (forall m mv. MVector mv m a => m (mv a)) @@ -23,6 +24,10 @@ {-# INLINE run #-} run (New p) = p +apply :: (forall mv a. MVectorPure mv a => mv a -> mv a) -> New a -> New a+{-# INLINE apply #-}+apply f (New p) = New (liftM f p)+ modify :: New a -> (forall m mv. MVector mv m a => mv a -> m ()) -> New a {-# INLINE modify #-} modify (New p) q = New (do { v <- p; q v; return v })@@ -43,7 +48,55 @@          p .   transform f (transform g p) = transform (f . g) p +"transform/unstream [New]"+  forall (f :: forall m. Monad m => MStream m a -> MStream m a)+         s.+  transform f (unstream s) = unstream (f s)+  #-}++slice :: New a -> Int -> Int -> New a+{-# INLINE_STREAM slice #-}+slice m i n = apply (\v -> MVector.slice v i n) m++init :: New a -> New a+{-# INLINE_STREAM init #-}+init m = apply (\v -> MVector.slice v 0 (MVector.length v - 1)) m++tail :: New a -> New a+{-# INLINE_STREAM tail #-}+tail m = apply (\v -> MVector.slice v 1 (MVector.length v - 1)) m++take :: Int -> New a -> New a+{-# INLINE_STREAM take #-}+take n m = apply (\v -> MVector.slice v 0 (min n (MVector.length v))) m++drop :: Int -> New a -> New a+{-# INLINE_STREAM drop #-}+drop n m = apply (\v -> MVector.slice v n (max 0 (MVector.length v - n))) m++{-# RULES++"slice/unstream [New]" forall s i n.+  slice (unstream s) i n = unstream (Stream.extract s i n)++"init/unstream [New]" forall s.+  init (unstream s) = unstream (Stream.init s)++"tail/unstream [New]" forall s.+  tail (unstream s) = unstream (Stream.tail s)++"take/unstream [New]" forall n s.+  take n (unstream s) = unstream (Stream.take n s)++"drop/unstream [New]" forall n s.+  drop n (unstream s) = unstream (Stream.drop n s)++  #-}++accum :: (a -> b -> a) -> New a -> Stream (Int, b) -> New a+{-# INLINE_STREAM accum #-}+accum f m s = modify m (\v -> MVector.accum f v s)  update :: New a -> Stream (Int, a) -> New a {-# INLINE_STREAM update #-}
− Data/Vector/Mutable.hs
@@ -1,77 +0,0 @@-{-# LANGUAGE MagicHash, UnboxedTuples, MultiParamTypeClasses, FlexibleInstances #-}---- |--- Module      : Data.Vector.Mutable--- Copyright   : (c) Roman Leshchinskiy 2008--- License     : BSD-style------ Maintainer  : Roman Leshchinskiy <rl@cse.unsw.edu.au>--- Stability   : experimental--- Portability : non-portable--- --- Mutable boxed vectors.-----module Data.Vector.Mutable ( Vector(..) )-where--import qualified Data.Vector.MVector as MVector-import           Data.Vector.MVector ( MVector, MVectorPure )--import GHC.Prim ( MutableArray#,-                  newArray#, readArray#, writeArray#, sameMutableArray#, (+#) )--import GHC.ST   ( ST(..) )--import GHC.Base ( Int(..) )---- | Mutable boxed vectors. They live in the 'ST' monad.-data Vector s a = Vector {-# UNPACK #-} !Int-                         {-# UNPACK #-} !Int-                                        (MutableArray# s a)--instance MVectorPure (Vector s) a where-  length (Vector _ n _) = n-  unsafeSlice (Vector i _ arr#) j m = Vector (i+j) m arr#--  {-# INLINE overlaps #-}-  overlaps (Vector i m arr1#) (Vector j n arr2#)-    = sameMutableArray# arr1# arr2#-      && (between i j (j+n) || between j i (i+m))-    where-      between x y z = x >= y && x < z---instance MVector (Vector s) (ST s) a where-  {-# INLINE unsafeNew #-}-  unsafeNew = unsafeNew--  {-# INLINE unsafeNewWith #-}-  unsafeNewWith = unsafeNewWith--  {-# INLINE unsafeRead #-}-  unsafeRead (Vector (I# i#) _ arr#) (I# j#) = ST (readArray# arr# (i# +# j#))--  {-# INLINE unsafeWrite #-}-  unsafeWrite (Vector (I# i#) _ arr#) (I# j#) x = ST (\s# ->-      case writeArray# arr# (i# +# j#) x s# of s2# -> (# s2#, () #)-    )--  {-# INLINE clear #-}-  clear v = MVector.set v uninitialised---uninitialised :: a-uninitialised = error "Data.Vector.Mutable: uninitialised elemen t"--unsafeNew :: Int -> ST s (Vector s a)-{-# INLINE unsafeNew #-}-unsafeNew n = unsafeNewWith n uninitialised--unsafeNewWith :: Int -> a -> ST s (Vector s a)-{-# INLINE unsafeNewWith #-}-unsafeNewWith (I# n#) x = ST (\s# ->-    case newArray# n# x s# of-      (# s2#, arr# #) -> (# s2#, Vector 0 (I# n#) arr# #)-  )-
+ Data/Vector/Mutable/IO.hs view
@@ -0,0 +1,58 @@+{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-}++-- |+-- Module      : Data.Vector.Mutable.IO+-- Copyright   : (c) Roman Leshchinskiy 2009+-- License     : BSD-style+--+-- Maintainer  : Roman Leshchinskiy <rl@cse.unsw.edu.au>+-- Stability   : experimental+-- Portability : non-portable+-- +-- Mutable boxed vectors in the IO monad.+--++module Data.Vector.Mutable.IO ( Vector(..) )+where++import           Data.Vector.MVector ( MVector(..), MVectorPure(..) )+import qualified Data.Vector.Mutable.ST as STV++import GHC.Base   ( RealWorld )+import GHC.ST     ( ST(..) )+import GHC.IOBase ( IO(..) )++import Prelude hiding ( length )++-- | IO-based mutable vectors+newtype Vector a = Vector (STV.Vector RealWorld a)++instance MVectorPure Vector a where+  {-# INLINE length #-}+  length (Vector v) = length v++  {-# INLINE unsafeSlice #-}+  unsafeSlice (Vector v) j m = Vector (unsafeSlice v j m)++  {-# INLINE overlaps #-}+  overlaps (Vector v1) (Vector v2) = overlaps v1 v2++instance MVector Vector IO a where+  {-# INLINE unsafeNew #-}+  unsafeNew n = Vector `fmap` stToIO (unsafeNew n)++  {-# INLINE unsafeNewWith #-}+  unsafeNewWith n x = Vector `fmap` stToIO (unsafeNewWith n x)++  {-# INLINE unsafeRead #-}+  unsafeRead (Vector v) i = stToIO (unsafeRead v i)++  {-# INLINE unsafeWrite #-}+  unsafeWrite (Vector v) i x = stToIO (unsafeWrite v i x)++  {-# INLINE clear #-}+  clear (Vector v) = stToIO (clear v)++stToIO :: ST RealWorld a -> IO a+stToIO (ST m) = IO m+
+ Data/Vector/Mutable/ST.hs view
@@ -0,0 +1,77 @@+{-# LANGUAGE MagicHash, UnboxedTuples, MultiParamTypeClasses, FlexibleInstances #-}++-- |+-- Module      : Data.Vector.Mutable.ST+-- Copyright   : (c) Roman Leshchinskiy 2008+-- License     : BSD-style+--+-- Maintainer  : Roman Leshchinskiy <rl@cse.unsw.edu.au>+-- Stability   : experimental+-- Portability : non-portable+-- +-- Mutable boxed vectors in the ST monad.+--++module Data.Vector.Mutable.ST ( Vector(..) )+where++import qualified Data.Vector.MVector as MVector+import           Data.Vector.MVector ( MVector, MVectorPure )++import GHC.Prim ( MutableArray#,+                  newArray#, readArray#, writeArray#, sameMutableArray#, (+#) )++import GHC.ST   ( ST(..) )++import GHC.Base ( Int(..) )++-- | Mutable boxed vectors. They live in the 'ST' monad.+data Vector s a = Vector {-# UNPACK #-} !Int+                         {-# UNPACK #-} !Int+                                        (MutableArray# s a)++instance MVectorPure (Vector s) a where+  length (Vector _ n _) = n+  unsafeSlice (Vector i _ arr#) j m = Vector (i+j) m arr#++  {-# INLINE overlaps #-}+  overlaps (Vector i m arr1#) (Vector j n arr2#)+    = sameMutableArray# arr1# arr2#+      && (between i j (j+n) || between j i (i+m))+    where+      between x y z = x >= y && x < z+++instance MVector (Vector s) (ST s) a where+  {-# INLINE unsafeNew #-}+  unsafeNew = unsafeNew++  {-# INLINE unsafeNewWith #-}+  unsafeNewWith = unsafeNewWith++  {-# INLINE unsafeRead #-}+  unsafeRead (Vector (I# i#) _ arr#) (I# j#) = ST (readArray# arr# (i# +# j#))++  {-# INLINE unsafeWrite #-}+  unsafeWrite (Vector (I# i#) _ arr#) (I# j#) x = ST (\s# ->+      case writeArray# arr# (i# +# j#) x s# of s2# -> (# s2#, () #)+    )++  {-# INLINE clear #-}+  clear v = MVector.set v uninitialised+++uninitialised :: a+uninitialised = error "Data.Vector.Mutable: uninitialised elemen t"++unsafeNew :: Int -> ST s (Vector s a)+{-# INLINE unsafeNew #-}+unsafeNew n = unsafeNewWith n uninitialised++unsafeNewWith :: Int -> a -> ST s (Vector s a)+{-# INLINE unsafeNewWith #-}+unsafeNewWith (I# n#) x = ST (\s# ->+    case newArray# n# x s# of+      (# s2#, arr# #) -> (# s2#, Vector 0 (I# n#) arr# #)+  )+
Data/Vector/Unboxed.hs view
@@ -13,11 +13,57 @@ --  module Data.Vector.Unboxed (-  Vector(..), module Data.Vector.IVector+  Vector,++  -- * Length information+  length, null,++  -- * Construction+  empty, singleton, cons, snoc, replicate, (++), copy,++  -- * Accessing individual elements+  (!), head, last,++  -- * Subvectors+  slice, init, tail, take, drop,++  -- * Permutations+  accum, (//), backpermute, reverse,++  -- * Mapping+  map, concatMap,++  -- * Zipping and unzipping+  zipWith, zipWith3,++  -- * Filtering+  filter, takeWhile, dropWhile,++  -- * Searching+  elem, notElem, find, findIndex,++  -- * Folding+  foldl, foldl1, foldl', foldl1', foldr, foldr1,++  -- * Specialised folds+  {-and, or,-} sum, product, maximum, minimum,++  -- * Unfolding+  unfoldr,++  -- * Scans+  prescanl, prescanl',++  -- * Enumeration+  enumFromTo, enumFromThenTo,++  -- * Conversion to/from lists+  toList, fromList ) where -import           Data.Vector.IVector-import qualified Data.Vector.Unboxed.Mutable as Mut+import           Data.Vector.IVector ( IVector(..) )+import qualified Data.Vector.IVector            as IV+import qualified Data.Vector.Unboxed.Mutable.ST as Mut import           Data.Vector.Unboxed.Unbox  import Control.Monad.ST ( runST )@@ -26,11 +72,28 @@ import GHC.Prim ( ByteArray#, unsafeFreezeByteArray#, (+#) ) import GHC.Base ( Int(..) ) +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, minimum, maximum,+                        enumFromTo, enumFromThenTo )++import qualified Prelude+ -- | Unboxed vectors data Vector a = Vector {-# UNPACK #-} !Int                        {-# UNPACK #-} !Int                                       ByteArray# +instance (Show a, Unbox a) => Show (Vector a) where+    show = (Prelude.++ " :: Data.Vector.Unboxed.Vector") . ("fromList " Prelude.++) . show . toList+ instance Unbox a => IVector Vector a where   {-# INLINE vnew #-}   vnew init = runST (do@@ -44,14 +107,310 @@   {-# INLINE unsafeSlice #-}   unsafeSlice (Vector i _ arr#) j n = Vector (i+j) n arr# -  {-# INLINE unsafeIndex #-}-  unsafeIndex (Vector (I# i#) _ arr#) (I# j#) f = f (at# arr# (i# +# j#))+  {-# INLINE unsafeIndexM #-}+  unsafeIndexM (Vector (I# i#) _ arr#) (I# j#) = return (at# arr# (i# +# j#))  instance (Unbox a, Eq a) => Eq (Vector a) where   {-# INLINE (==) #-}-  (==) = eq+  (==) = IV.eq  instance (Unbox a, Ord a) => Ord (Vector a) where   {-# INLINE compare #-}-  compare = cmp+  compare = IV.cmp++-- Length+-- ------++length :: Unbox a => Vector a -> Int+{-# INLINE length #-}+length = IV.length++null :: Unbox a => Vector a -> Bool+{-# INLINE null #-}+null = IV.null++-- Construction+-- ------------++-- | Empty vector+empty :: Unbox a => Vector a+{-# INLINE empty #-}+empty = IV.empty++-- | Vector with exaclty one element+singleton :: Unbox a => a -> Vector a+{-# INLINE singleton #-}+singleton = IV.singleton++-- | Vector of the given length with the given value in each position+replicate :: Unbox a => Int -> a -> Vector a+{-# INLINE replicate #-}+replicate = IV.replicate++-- | Prepend an element+cons :: Unbox a => a -> Vector a -> Vector a+{-# INLINE cons #-}+cons = IV.cons++-- | Append an element+snoc :: Unbox a => Vector a -> a -> Vector a+{-# INLINE snoc #-}+snoc = IV.snoc++infixr 5 +++-- | Concatenate two vectors+(++) :: Unbox a => Vector a -> Vector a -> Vector a+{-# INLINE (++) #-}+(++) = (IV.++)++-- | Create a copy of a vector. Useful when dealing with slices.+copy :: Unbox a => Vector a -> Vector a+{-# INLINE copy #-}+copy = IV.copy++-- Accessing individual elements+-- -----------------------------++-- | Indexing+(!) :: Unbox a => Vector a -> Int -> a+{-# INLINE (!) #-}+(!) = (IV.!)++-- | First element+head :: Unbox a => Vector a -> a+{-# INLINE head #-}+head = IV.head++-- | Last element+last :: Unbox a => Vector a -> a+{-# INLINE last #-}+last = IV.last++-- Subarrays+-- ---------++-- | Yield a part of the vector without copying it. Safer version of+-- 'unsafeSlice'.+slice :: Unbox a => Vector a -> Int   -- ^ starting index+                             -> Int   -- ^ length+                             -> Vector a+{-# INLINE slice #-}+slice = IV.slice++-- | Yield all but the last element without copying.+init :: Unbox a => Vector a -> Vector a+{-# INLINE init #-}+init = IV.init++-- | All but the first element (without copying).+tail :: Unbox a => Vector a -> Vector a+{-# INLINE tail #-}+tail = IV.tail++-- | Yield the first @n@ elements without copying.+take :: Unbox a => Int -> Vector a -> Vector a+{-# INLINE take #-}+take = IV.take++-- | Yield all but the first @n@ elements without copying.+drop :: Unbox a => Int -> Vector a -> Vector a+{-# INLINE drop #-}+drop = IV.drop++-- Permutations+-- ------------++accum :: Unbox a => (a -> b -> a) -> Vector a -> [(Int,b)] -> Vector a+{-# INLINE accum #-}+accum = IV.accum++(//) :: Unbox a => Vector a -> [(Int, a)] -> Vector a+{-# INLINE (//) #-}+(//) = (IV.//)++backpermute :: Unbox a => Vector a -> Vector Int -> Vector a+{-# INLINE backpermute #-}+backpermute = IV.backpermute++reverse :: Unbox a => Vector a -> Vector a+{-# INLINE reverse #-}+reverse = IV.reverse++-- Mapping+-- -------++-- | Map a function over a vector+map :: (Unbox a, Unbox b) => (a -> b) -> Vector a -> Vector b+{-# INLINE map #-}+map = IV.map++concatMap :: (Unbox a, Unbox b) => (a -> Vector b) -> Vector a -> Vector b+{-# INLINE concatMap #-}+concatMap = IV.concatMap++-- Zipping/unzipping+-- -----------------++-- | Zip two vectors with the given function.+zipWith :: (Unbox a, Unbox b, Unbox c)+        => (a -> b -> c) -> Vector a -> Vector b -> Vector c+{-# INLINE zipWith #-}+zipWith = IV.zipWith++-- | Zip three vectors with the given function.+zipWith3 :: (Unbox a, Unbox b, Unbox c, Unbox d)+         => (a -> b -> c -> d) -> Vector a -> Vector b -> Vector c -> Vector d+{-# INLINE zipWith3 #-}+zipWith3 = IV.zipWith3++-- Filtering+-- ---------++-- | Drop elements which do not satisfy the predicate+filter :: Unbox a => (a -> Bool) -> Vector a -> Vector a+{-# INLINE filter #-}+filter = IV.filter++-- | Yield the longest prefix of elements satisfying the predicate.+takeWhile :: Unbox a => (a -> Bool) -> Vector a -> Vector a+{-# INLINE takeWhile #-}+takeWhile = IV.takeWhile++-- | Drop the longest prefix of elements that satisfy the predicate.+dropWhile :: Unbox a => (a -> Bool) -> Vector a -> Vector a+{-# INLINE dropWhile #-}+dropWhile = IV.dropWhile++-- Searching+-- ---------++infix 4 `elem`+-- | Check whether the vector contains an element+elem :: (Unbox a, Eq a) => a -> Vector a -> Bool+{-# INLINE elem #-}+elem = IV.elem++infix 4 `notElem`+-- | Inverse of `elem`+notElem :: (Unbox a, Eq a) => a -> Vector a -> Bool+{-# INLINE notElem #-}+notElem = IV.notElem++-- | Yield 'Just' the first element matching the predicate or 'Nothing' if no+-- such element exists.+find :: Unbox a => (a -> Bool) -> Vector a -> Maybe a+{-# INLINE find #-}+find = IV.find++-- | Yield 'Just' the index of the first element matching the predicate or+-- 'Nothing' if no such element exists.+findIndex :: Unbox a => (a -> Bool) -> Vector a -> Maybe Int+{-# INLINE findIndex #-}+findIndex = IV.findIndex++-- Folding+-- -------++-- | Left fold+foldl :: Unbox b => (a -> b -> a) -> a -> Vector b -> a+{-# INLINE foldl #-}+foldl = IV.foldl++-- | Lefgt fold on non-empty vectors+foldl1 :: Unbox a => (a -> a -> a) -> Vector a -> a+{-# INLINE foldl1 #-}+foldl1 = IV.foldl1++-- | Left fold with strict accumulator+foldl' :: Unbox b => (a -> b -> a) -> a -> Vector b -> a+{-# INLINE foldl' #-}+foldl' = IV.foldl'++-- | Left fold on non-empty vectors with strict accumulator+foldl1' :: Unbox a => (a -> a -> a) -> Vector a -> a+{-# INLINE foldl1' #-}+foldl1' = IV.foldl1'++-- | Right fold+foldr :: Unbox a => (a -> b -> b) -> b -> Vector a -> b+{-# INLINE foldr #-}+foldr = IV.foldr++-- | Right fold on non-empty vectors+foldr1 :: Unbox a => (a -> a -> a) -> Vector a -> a+{-# INLINE foldr1 #-}+foldr1 = IV.foldr1++-- Specialised folds+-- -----------------++{-+and :: Vector Bool -> Bool+{-# INLINE and #-}+and = IV.and++or :: Vector Bool -> Bool+{-# INLINE or #-}+or = IV.or+-}++sum :: (Unbox a, Num a) => Vector a -> a+{-# INLINE sum #-}+sum = IV.sum++product :: (Unbox a, Num a) => Vector a -> a+{-# INLINE product #-}+product = IV.product++maximum :: (Unbox a, Ord a) => Vector a -> a+{-# INLINE maximum #-}+maximum = IV.maximum++minimum :: (Unbox a, Ord a) => Vector a -> a+{-# INLINE minimum #-}+minimum = IV.minimum++-- Unfolding+-- ---------++unfoldr :: Unbox a => (b -> Maybe (a, b)) -> b -> Vector a+{-# INLINE unfoldr #-}+unfoldr = IV.unfoldr++-- Scans+-- -----++-- | Prefix scan+prescanl :: (Unbox a, Unbox b) => (a -> b -> a) -> a -> Vector b -> Vector a+{-# INLINE prescanl #-}+prescanl = IV.prescanl++-- | Prefix scan with strict accumulator+prescanl' :: (Unbox a, Unbox b) => (a -> b -> a) -> a -> Vector b -> Vector a+{-# INLINE prescanl' #-}+prescanl' = IV.prescanl'++-- Enumeration+-- -----------++enumFromTo :: (Unbox a, Enum a) => a -> a -> Vector a+{-# INLINE enumFromTo #-}+enumFromTo = IV.enumFromTo++enumFromThenTo :: (Unbox a, Enum a) => a -> a -> a -> Vector a+{-# INLINE enumFromThenTo #-}+enumFromThenTo = IV.enumFromThenTo++-- Conversion to/from lists+-- ------------------------++-- | Convert a vector to a list+toList :: Unbox a => Vector a -> [a]+{-# INLINE toList #-}+toList = IV.toList++-- | Convert a list to a vector+fromList :: Unbox a => [a] -> Vector a+{-# INLINE fromList #-}+fromList = IV.fromList 
− Data/Vector/Unboxed/Mutable.hs
@@ -1,63 +0,0 @@-{-# LANGUAGE MagicHash, UnboxedTuples, MultiParamTypeClasses, FlexibleInstances, ScopedTypeVariables #-}---- |--- Module      : Data.Vector.Unboxed.Mutable--- Copyright   : (c) Roman Leshchinskiy 2008--- License     : BSD-style------ Maintainer  : Roman Leshchinskiy <rl@cse.unsw.edu.au>--- Stability   : experimental--- Portability : non-portable--- --- Mutable unboxed vectors based on 'Unbox'.-----module Data.Vector.Unboxed.Mutable ( Vector(..) )-where--import qualified Data.Vector.MVector as MVector-import           Data.Vector.MVector ( MVector, MVectorPure )-import           Data.Vector.Unboxed.Unbox--import GHC.Prim ( MutableByteArray#,-                  newByteArray#, sameMutableByteArray#, (+#) )--import GHC.ST   ( ST(..) )--import GHC.Base ( Int(..) )---- | Mutable unboxed vectors. They live in the 'ST' monad.-data Vector s a = Vector {-# UNPACK #-} !Int-                         {-# UNPACK #-} !Int-                                        (MutableByteArray# s)--instance Unbox a => MVectorPure (Vector s) a where-  length (Vector _ n _) = n-  unsafeSlice (Vector i _ arr#) j m = Vector (i+j) m arr#--  {-# INLINE overlaps #-}-  overlaps (Vector i m arr1#) (Vector j n arr2#)-    = sameMutableByteArray# arr1# arr2#-      && (between i j (j+n) || between j i (i+m))-    where-      between x y z = x >= y && x < z---instance Unbox a => MVector (Vector s) (ST s) a where-  {-# INLINE unsafeNew #-}-  unsafeNew (I# n#) = ST (\s# ->-      case newByteArray# (size# (undefined :: a) n#) s# of-        (# s2#, arr# #) -> (# s2#, Vector 0 (I# n#) arr# #)-    )--  {-# INLINE unsafeRead #-}-  unsafeRead (Vector (I# i#) _ arr#) (I# j#) = ST (read# arr# (i# +# j#))--  {-# INLINE unsafeWrite #-}-  unsafeWrite (Vector (I# i#) _ arr#) (I# j#) x = ST (\s# ->-      case write# arr# (i# +# j#) x s# of s2# -> (# s2#, () #)-    )--  {-# INLINE clear #-}-  clear _ = return ()-
+ Data/Vector/Unboxed/Mutable/IO.hs view
@@ -0,0 +1,59 @@+{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-}++-- |+-- Module      : Data.Vector.Mutable.Unboxed.IO+-- Copyright   : (c) Roman Leshchinskiy 2009+-- License     : BSD-style+--+-- Maintainer  : Roman Leshchinskiy <rl@cse.unsw.edu.au>+-- Stability   : experimental+-- Portability : non-portable+-- +-- Mutable unboxed vectors in the IO monad.+--++module Data.Vector.Unboxed.Mutable.IO ( Vector(..) )+where++import           Data.Vector.MVector ( MVector(..), MVectorPure(..) )+import qualified Data.Vector.Unboxed.Mutable.ST as STV+import           Data.Vector.Unboxed.Unbox ( Unbox )++import GHC.Base   ( RealWorld )+import GHC.ST     ( ST(..) )+import GHC.IOBase ( IO(..) )++import Prelude hiding ( length )++-- | IO-based mutable vectors+newtype Vector a = Vector (STV.Vector RealWorld a)++instance Unbox a => MVectorPure Vector a where+  {-# INLINE length #-}+  length (Vector v) = length v++  {-# INLINE unsafeSlice #-}+  unsafeSlice (Vector v) j m = Vector (unsafeSlice v j m)++  {-# INLINE overlaps #-}+  overlaps (Vector v1) (Vector v2) = overlaps v1 v2++instance Unbox a => MVector Vector IO a where+  {-# INLINE unsafeNew #-}+  unsafeNew n = Vector `fmap` stToIO (unsafeNew n)++  {-# INLINE unsafeNewWith #-}+  unsafeNewWith n x = Vector `fmap` stToIO (unsafeNewWith n x)++  {-# INLINE unsafeRead #-}+  unsafeRead (Vector v) i = stToIO (unsafeRead v i)++  {-# INLINE unsafeWrite #-}+  unsafeWrite (Vector v) i x = stToIO (unsafeWrite v i x)++  {-# INLINE clear #-}+  clear (Vector v) = stToIO (clear v)++stToIO :: ST RealWorld a -> IO a+stToIO (ST m) = IO m+
+ Data/Vector/Unboxed/Mutable/ST.hs view
@@ -0,0 +1,63 @@+{-# LANGUAGE MagicHash, UnboxedTuples, MultiParamTypeClasses, FlexibleInstances, ScopedTypeVariables #-}++-- |+-- Module      : Data.Vector.Unboxed.Mutable.ST+-- Copyright   : (c) Roman Leshchinskiy 2008+-- License     : BSD-style+--+-- Maintainer  : Roman Leshchinskiy <rl@cse.unsw.edu.au>+-- Stability   : experimental+-- Portability : non-portable+-- +-- Mutable unboxed vectors based on 'Unbox' in the ST monad.+--++module Data.Vector.Unboxed.Mutable.ST ( Vector(..) )+where++import qualified Data.Vector.MVector as MVector+import           Data.Vector.MVector ( MVector, MVectorPure )+import           Data.Vector.Unboxed.Unbox++import GHC.Prim ( MutableByteArray#,+                  newByteArray#, sameMutableByteArray#, (+#) )++import GHC.ST   ( ST(..) )++import GHC.Base ( Int(..) )++-- | Mutable unboxed vectors. They live in the 'ST' monad.+data Vector s a = Vector {-# UNPACK #-} !Int+                         {-# UNPACK #-} !Int+                                        (MutableByteArray# s)++instance Unbox a => MVectorPure (Vector s) a where+  length (Vector _ n _) = n+  unsafeSlice (Vector i _ arr#) j m = Vector (i+j) m arr#++  {-# INLINE overlaps #-}+  overlaps (Vector i m arr1#) (Vector j n arr2#)+    = sameMutableByteArray# arr1# arr2#+      && (between i j (j+n) || between j i (i+m))+    where+      between x y z = x >= y && x < z+++instance Unbox a => MVector (Vector s) (ST s) a where+  {-# INLINE unsafeNew #-}+  unsafeNew (I# n#) = ST (\s# ->+      case newByteArray# (size# (undefined :: a) n#) s# of+        (# s2#, arr# #) -> (# s2#, Vector 0 (I# n#) arr# #)+    )++  {-# INLINE unsafeRead #-}+  unsafeRead (Vector (I# i#) _ arr#) (I# j#) = ST (read# arr# (i# +# j#))++  {-# INLINE unsafeWrite #-}+  unsafeWrite (Vector (I# i#) _ arr#) (I# j#) x = ST (\s# ->+      case write# arr# (i# +# j#) x s# of s2# -> (# s2#, () #)+    )++  {-# INLINE clear #-}+  clear _ = return ()+
Data/Vector/Unboxed/Unbox.hs view
@@ -22,11 +22,15 @@ import GHC.Float (     Float(..), Double(..)   )+import GHC.Word (+    Word(..)+  )  import GHC.Prim (     ByteArray#, MutableByteArray#, State#,      Int#, indexIntArray#,    readIntArray#,    writeIntArray#,+          indexWordArray#,   readWordArray#,   writeWordArray#,           indexFloatArray#,  readFloatArray#,  writeFloatArray#,           indexDoubleArray#, readDoubleArray#, writeDoubleArray#   )@@ -49,6 +53,14 @@    -- | Store the given element at the given position   write# :: MutableByteArray# s -> Int# -> a -> State# s -> State# s++instance Unbox Word where+  size# _                   = wORD_SCALE+  at#    arr# i#            = W# (indexWordArray# arr# i#)+  read#  arr# i# s#         = case readWordArray# arr# i# s# of+                                (# s1#, n# #) -> (# s1#, W# n# #)+  write# arr# i# (W# n#) s# = writeWordArray# arr# i# n# s#+  instance Unbox Int where   size#  _                  = wORD_SCALE
LICENSE view
@@ -1,5 +1,4 @@-Copyright (c) 2001-2002, Manuel M T Chakravarty & Gabriele Keller-Copyright (c) 2006-2007, Manuel M T Chakravarty & Roman Leshchinskiy+Copyright (c) 2008-2009, Roman Leshchinskiy All rights reserved.  Redistribution and use in source and binary forms, with or without
vector.cabal view
@@ -1,5 +1,5 @@ Name:           vector-Version:        0.2+Version:        0.3 License:        BSD3 License-File:   LICENSE Author:         Roman Leshchinskiy@@ -10,18 +10,23 @@ Synopsis:       Efficient Arrays Description:         .-        An efficient implementation of Int-indexed arrays with a powerful-        loop fusion framework.+        An efficient but highly experimental implementation of Int-indexed+        arrays with a powerful loop fusion framework.         .-        This code is highly experimental and for the most part untested. Use-        at your own risk!  Cabal-Version:  >= 1.2 Build-Type:     Simple +Flag EnableAssertions+  Description: Enable assertions that check parameters to functions are reasonable.+               These will impose a moderate performance cost on users of the library,+               with the benefit that you get reasonable errors rather than segmentation faults!+  Default:     False+ Library   Extensions: CPP   Exposed-Modules:+        Data.Vector.Fusion.Util         Data.Vector.Fusion.Stream.Size         Data.Vector.Fusion.Stream.Monadic         Data.Vector.Fusion.Stream@@ -31,10 +36,12 @@         Data.Vector.IVector          Data.Vector.Unboxed.Unbox-        Data.Vector.Unboxed.Mutable+        Data.Vector.Unboxed.Mutable.ST+        Data.Vector.Unboxed.Mutable.IO         Data.Vector.Unboxed -        Data.Vector.Mutable+        Data.Vector.Mutable.ST+        Data.Vector.Mutable.IO         Data.Vector   Include-Dirs:         include@@ -42,6 +49,23 @@   Install-Includes:         phases.h -  Build-Depends: base, array, ghc-prim,+  Build-Depends: base >= 2 && < 4, array, ghc-prim,                  ghc >= 6.9 +-- -finline-if-enough-args is ESSENTIAL. If we don't have this the partial application+-- of e.g. Stream.Monadic.++ to the monad dictionary at the use site in Stream.++ causes+-- it to be fruitlessly inlined. This in turn leads to a huge RHS for Stream.++, so it+-- doesn't get inlined at the final call site and fusion fails to occur.+  Ghc-Options: -finline-if-enough-args+  +-- It's probably a good idea to compile the library with -O2 as well. However, it's probably+-- not as essential as you think because most of the optimisation occurs when the library+-- functions from here are inlined into the user programs (which SHOULD be compiled with -O2!).+--+-- We have to fiddle with the assertion stuff at this point too because -O2 implies -fno-ignore-asserts,+-- meaning that their relative ordering is CRUCIAL. Setting them together guarantees it.+  if flag(enableassertions)+    -- Asserts are ignored by default at -O1 or higher+    Ghc-Options: -O2 -fno-ignore-asserts+  else+    Ghc-Options: -O2