storablevector 0.1.0 → 0.1.1
raw patch · 6 files changed
+119/−85 lines, 6 filesdep +randomdep −haskell98dep ~QuickCheckdep ~basedep ~bytestring
Dependencies added: random
Dependencies removed: haskell98
Dependency ranges changed: QuickCheck, base, bytestring
Files
- Data/StorableVector.hs +51/−44
- storablevector.cabal +34/−16
- tests-1/Instances.hs +13/−0
- tests-2/Instances.hs +1/−0
- tests/QuickCheckUtils.hs +16/−23
- tests/tests.hs +4/−2
Data/StorableVector.hs view
@@ -411,7 +411,7 @@ -- reduces the 'Vector' using the binary operator, from right to left. foldr :: (Storable a) => (a -> b -> b) -> b -> Vector a -> b foldr k z =- let recurse = maybe z (\(h,t) -> k h (recurse t)) . viewL+ let recurse = switchL z (\h t -> k h (recurse t)) in recurse {-# INLINE foldr #-} @@ -420,32 +420,29 @@ -- This function is subject to array fusion. -- An exception will be thrown in the case of an empty 'Vector'. foldl1 :: (Storable a) => (a -> a -> a) -> Vector a -> a-foldl1 f ps =- maybe+foldl1 f =+ switchL (errorEmptyList "foldl1")- (\(h,t) -> foldl f h t)- (viewL ps)+ (foldl f) {-# INLINE foldl1 #-} -- | 'foldl1\'' is like 'foldl1', but strict in the accumulator. -- An exception will be thrown in the case of an empty 'Vector'. foldl1' :: (Storable a) => (a -> a -> a) -> Vector a -> a-foldl1' f ps =- maybe+foldl1' f =+ switchL (errorEmptyList "foldl1'")- (\(h,t) -> foldl' f h t)- (viewL ps)+ (foldl' f) {-# INLINE foldl1' #-} -- | 'foldr1' is a variant of 'foldr' that has no starting value argument, -- and thus must be applied to non-empty 'Vector's -- An exception will be thrown in the case of an empty 'Vector'. foldr1 :: (Storable a) => (a -> a -> a) -> Vector a -> a-foldr1 f ps =- maybe+foldr1 f =+ switchR (errorEmptyList "foldr1")- (\(i,l) -> foldr f l i)- (viewR ps)+ (flip (foldr f)) {-# INLINE foldr1 #-} -- ---------------------------------------------------------------------@@ -480,6 +477,7 @@ | otherwise = do c <- peek p if f c then return True else go (p `advancePtr` 1) q+{-# INLINE any #-} -- | /O(n)/ Applied to a predicate and a 'Vector', 'all' determines -- if all elements of the 'Vector' satisfy the predicate.@@ -494,6 +492,7 @@ if f c then go (p `advancePtr` 1) q else return False+{-# INLINE all #-} ------------------------------------------------------------------------ @@ -511,18 +510,28 @@ ------------------------------------------------------------------------ -viewL :: Storable a => Vector a -> Maybe (a, Vector a)-viewL x =+switchL :: Storable a => b -> (a -> Vector a -> b) -> Vector a -> b+switchL n j x = if null x- then Nothing- else Just (unsafeHead x, unsafeTail x)+ then n+ else j (unsafeHead x) (unsafeTail x)+{-# INLINE switchL #-} -viewR :: Storable a => Vector a -> Maybe (Vector a, a)-viewR x =+switchR :: Storable a => b -> (Vector a -> a -> b) -> Vector a -> b+switchR n j x = if null x- then Nothing- else Just (unsafeInit x, unsafeLast x)+ then n+ else j (unsafeInit x) (unsafeLast x)+{-# INLINE switchR #-} +viewL :: Storable a => Vector a -> Maybe (a, Vector a)+viewL = switchL Nothing (curry Just)+{-# INLINE viewL #-}++viewR :: Storable a => Vector a -> Maybe (Vector a, a)+viewR = switchR Nothing (curry Just)+{-# INLINE viewR #-}+ -- | The 'mapAccumL' function behaves like a combination of 'map' and -- 'foldl'; it applies a function to each element of a 'Vector', -- passing an accumulating parameter from left to right, and returning a@@ -601,8 +610,7 @@ -- -- > scanl1 f [x1, x2, ...] == [x1, x1 `f` x2, ...] scanl1 :: (Storable a) => (a -> a -> a) -> Vector a -> Vector a-scanl1 f ps =- maybe empty (uncurry (scanl f)) (viewL ps)+scanl1 f = switchL empty (scanl f) {-# INLINE scanl1 #-} -- | scanr is the right-to-left dual of scanl.@@ -621,8 +629,7 @@ -- | 'scanr1' is a variant of 'scanr' that has no starting value argument. scanr1 :: (Storable a) => (a -> a -> a) -> Vector a -> Vector a-scanr1 f ps =- maybe empty (uncurry (flip (scanl f))) (viewR ps)+scanr1 f = switchR empty (flip (scanl f)) {-# INLINE scanr1 #-} -- ---------------------------------------------------------------------@@ -654,6 +661,7 @@ case unfoldrN n f x of (s, Nothing) -> s : [] (s, Just x') -> s : unfoldChunk n' (n+n') x'+{-# INLINE unfoldr #-} -- | /O(n)/ Like 'unfoldr', 'unfoldrN' builds a 'Vector' from a seed -- value. However, the length of the result is limited by the first@@ -783,9 +791,7 @@ STRICT2(loop) loop q qs = chunk :- maybe []- (\(_,t) -> loop q t)- (viewL rest)+ switchL [] (\ _ t -> loop q t) rest where (chunk,rest) = break q qs {-# INLINE splitWith #-} @@ -830,27 +836,28 @@ -- /groupBy (==)/ group :: (Storable a, Eq a) => Vector a -> [Vector a] group xs =- maybe []- (\(h,_) ->+ switchL []+ (\ h _ -> let (ys, zs) = span (== h) xs in ys : group zs)- (viewL xs)+ xs -- | The 'groupBy' function is the non-overloaded version of 'group'. groupBy :: (Storable a) => (a -> a -> Bool) -> Vector a -> [Vector a] groupBy k xs =- maybe []- (\(h,t) ->+ switchL []+ (\ h t -> let n = 1 + findIndexOrEnd (not . k h) t in unsafeTake n xs : groupBy k (unsafeDrop n xs))- (viewL xs)+ xs+{-# INLINE groupBy #-} -- | /O(n)/ The 'join' function takes a 'Vector' and a list of -- 'Vector's and concatenates the list after interspersing the first -- argument between each element of the list. join :: (Storable a) => Vector a -> [Vector a] -> Vector a-join s = concat . (List.intersperse s)+join s = concat . List.intersperse s {-# INLINE join #-} -- ---------------------------------------------------------------------@@ -908,12 +915,12 @@ elemIndices c ps = loop 0 ps where STRICT2(loop) loop n ps' =- maybe []- (\(h,t) ->+ switchL []+ (\ h t -> if c == h then n : loop (n+1) t- else loop (n+1) t) $- viewL ps'+ else loop (n+1) t)+ ps' {-# INLINE elemIndices #-} -- | count returns the number of times its argument appears in the 'Vector' @@ -946,12 +953,13 @@ where STRICT2(loop) loop n qs =- maybe []- (\(h,t) ->+ switchL []+ (\ h t -> if p h then n : loop (n+1) t else loop (n+1) t) $- viewL qs+ qs+{-# INLINE findIndices #-} -- | 'findIndexOrEnd' is a variant of findIndex, that returns the length -- of the string if no element is found, rather than Nothing.@@ -1077,8 +1085,7 @@ -- | /O(n)/ Return all final segments of the given 'Vector', longest first. tails :: (Storable a) => Vector a -> [Vector a] tails p =- maybe [empty] (\(_,t) -> p : tails t) $- viewL p+ switchL [empty] (\ _ t -> p : tails t) p -- --------------------------------------------------------------------- -- ** Ordered 'Vector's
storablevector.cabal view
@@ -1,5 +1,5 @@ Name: storablevector-Version: 0.1.0+Version: 0.1.1 Category: Data Synopsis: Fast, packed, strict storable arrays with a list interface like ByteString Description:@@ -13,20 +13,38 @@ Package-URL: http://code.haskell.org/~sjanssen/storablevector Build-Depends: base Build-Type: Simple-Tested-With: GHC==6.4.1-Extensions: CPP, ForeignFunctionInterface-Exposed-modules: Data.StorableVector- Data.StorableVector.Base-GHC-Options: -Wall -fglasgow-exts -funbox-strict-fields-CPP-Options: -DSLOW_FOREIGN_PTR+Tested-With: GHC==6.4.1, GHC==6.8.2+Cabal-Version: >=1.2 --- -DSLOW_FOREIGN_PTR -Executable: test-GHC-Options: -Wall -fglasgow-exts -funbox-strict-fields-CPP-Options: -DSLOW_FOREIGN_PTR-Hs-Source-Dirs: ., tests-Main-Is: tests.hs-Other-Modules: QuickCheckUtils-Extensions: CPP, ForeignFunctionInterface-Build-Depends: base, haskell98, bytestring, QuickCheck+Flag splitBase+ description: Choose the new smaller, split-up base package.++Library+ If flag(splitBase)+ Build-Depends: base >= 3+ Else+ Build-Depends: base >= 1.0 && < 2++ Extensions: CPP, ForeignFunctionInterface+ GHC-Options: -Wall -funbox-strict-fields+ CPP-Options: -DSLOW_FOREIGN_PTR++ Exposed-modules:+ Data.StorableVector+ Data.StorableVector.Base+++Executable test+ GHC-Options: -Wall -funbox-strict-fields+ CPP-Options: -DSLOW_FOREIGN_PTR+ Main-Is: tests.hs+ Other-Modules: QuickCheckUtils, Instances+ Build-Depends: bytestring >= 0.9 && < 0.10, QuickCheck >= 1 && < 2+ Extensions: CPP, ForeignFunctionInterface+ If flag(splitBase)+ Hs-Source-Dirs: ., tests, tests-2+ Build-Depends: base >= 3, random >= 1.0 && < 1.1+ Else+ Hs-Source-Dirs: ., tests, tests-1+ Build-Depends: base >= 1.0 && < 2
+ tests-1/Instances.hs view
@@ -0,0 +1,13 @@+module Instances where+++instance Functor ((->) r) where+ fmap = (.)++instance Monad ((->) r) where+ return = const+ f >>= k = \ r -> k (f r) r++instance Functor ((,) a) where+ fmap f (x,y) = (x, f y)+
+ tests-2/Instances.hs view
@@ -0,0 +1,1 @@+module Instances where
tests/QuickCheckUtils.hs view
@@ -4,21 +4,23 @@ -- module QuickCheckUtils where -import Test.QuickCheck.Batch+import Instances ()+ import Test.QuickCheck-import Text.Show.Functions+-- import Test.QuickCheck (Arbitrary(arbitrary, coarbitrary), variant, choose, sized, (==>), Property, )+import Text.Show.Functions ()+import System.Random (RandomGen, StdGen, Random, newStdGen, split, randomR, random, ) -import Control.Monad ( liftM2 )-import Data.Char-import Data.List-import Data.Word-import Data.Int-import System.Random-import System.IO+import Control.Monad (liftM2)+import Data.Char (ord)+import Data.Word (Word8)+import Data.Int (Int64)+import System.IO (hFlush, stdout, ) -import Data.ByteString.Fusion+import Data.ByteString.Fusion (PairS((:*:)), MaybeS(JustS, NothingS), ) import qualified Data.ByteString as P import qualified Data.StorableVector as V+import qualified Data.List as List import qualified Data.ByteString.Char8 as PC @@ -63,10 +65,10 @@ table = display . map entry . reverse- . sort+ . List.sort . map pairLength- . group- . sort+ . List.group+ . List.sort . filter (not . null) $ stamps @@ -77,7 +79,7 @@ pairLength xss@(xs:_) = (length xss, xs) entry (n, xs) = percentage n ntest ++ " "- ++ concat (intersperse ", " xs)+ ++ concat (List.intersperse ", " xs) percentage n m = show ((100 * n) `div` m) ++ "%" @@ -135,15 +137,6 @@ arbitrary = P.pack `fmap` arbitrary coarbitrary s = coarbitrary (P.unpack s) -instance Functor ((->) r) where- fmap = (.)--instance Monad ((->) r) where- return = const- f >>= k = \ r -> k (f r) r--instance Functor ((,) a) where- fmap f (x,y) = (x, f y) ------------------------------------------------------------------------ --
tests/tests.hs view
@@ -2,8 +2,10 @@ import qualified Data.StorableVector as V import qualified Data.ByteString as P import QuickCheckUtils-import Text.Printf-import System (getArgs)+ (V, W, X, P, mytest,+ eq1, eq2, eq3, eqnotnull1, eqnotnull2, eqnotnull3, )+import Text.Printf (printf)+import System.Environment (getArgs) -- -- Data.StorableVector <=> ByteString