packages feed

binary-list 0.3.2.1 → 0.3.3.0

raw patch · 4 files changed

+117/−9 lines, 4 filesdep +phantom-statePVP ok

version bump matches the API change (PVP)

Dependencies added: phantom-state

API changes (from Hackage documentation)

+ Data.BinaryList: generateM :: (Applicative m, Monad m) => Int -> (Int -> m a) -> m (BinList a)
+ Data.BinaryList: toListFilter :: (a -> Bool) -> BinList a -> [a]
+ Data.BinaryList: toListSegment :: Int -> Int -> BinList a -> [a]
+ Data.BinaryList: traverseSegment :: Applicative f => (a -> f ()) -> Int -> Int -> BinList a -> f ()
+ Data.BinaryList.Serialize: instance Show Direction
+ Data.BinaryList.Serialize: instance Show a => Show (Decoded a)

Files

Data/BinaryList.hs view
@@ -40,6 +40,7 @@   , replicateA   , replicateAR   , generate+  , generateM     -- * Queries   , lengthIndex   , length@@ -59,13 +60,21 @@   , zip , unzip   , zipWith     -- * Lists+    -- ** From list   , fromList   , fromListWithDefault+    -- ** To list+  , toListFilter+  , toListSegment+    -- * Others+  , traverseSegment     -- * Example: Radix-2 FFT     -- $fft   ) where -import Prelude hiding ( length,lookup,replicate,head,last,zip,unzip,zipWith,reverse,foldr1,take,map )+import Prelude hiding ( length,lookup,replicate,head,last+                      , zip,unzip,zipWith,reverse,foldr1+                      , take,map,foldr ) import qualified Prelude import Foreign.Storable (sizeOf) import Data.List (find)@@ -76,8 +85,10 @@ import Data.Monoid (mappend) import Data.Foldable (Foldable (..),toList) import Data.Traversable (Traversable (..))-import Control.Monad.Trans.State (StateT (..),evalState,get,modify)+import Control.Monad.Trans.State (StateT (..),evalStateT,evalState,get,modify)+import Control.Monad.Trans.Class (lift) import Data.Functor.Identity (Identity (..))+import Control.Applicative.PhantomState  -- | /O(1)/. Build a list with a single element. singleton :: a -> BinList a@@ -176,6 +187,11 @@ generate :: Int -> (Int -> a) -> BinList a generate l f = evalState (replicateA l $ fmap f get <* modify (+1)) 0 +-- | Like 'generate', but the generator function returns a value in a 'Monad'.+--   Therefore, the result is as well contained in a 'Monad'.+generateM :: (Applicative m, Monad m) => Int -> (Int -> m a) -> m (BinList a)+generateM l f = evalStateT (replicateA l $ (get >>= lift . f) <* modify (+1)) 0+ -- | /O(log n)/. Get the first element of a binary list. head :: BinList a -> a head (ListNode _ l _) = head l@@ -384,8 +400,88 @@                       (h:t) -> (h,t)                       [] -> (e,[])                ) xs-        _ -> error "fromListWithDefault: input list is too big."+        _ -> error "[binary-list] fromListWithDefault: input list is too big." +{-# INLINE toListFilter #-}++-- | /O(n)/. Create a list from the elements of a binary list matching a given+--   condition.+toListFilter :: (a -> Bool) -> BinList a -> [a]+toListFilter c = foldr (\x -> if c x then (x:) else id) []++-- | /O(n)/. Create a list extracting a sublist of elements from a binary list.+toListSegment :: Int -> Int -> BinList a -> [a]+{-# INLINE toListSegment #-}+toListSegment s e xs = runPhantomState (traverseSegment (changeState . (:)) s e xs) []++{-# INLINE traverseSegment #-}++-- | Apply an applicative action to every element in a segment of a binary list, from left to right.+traverseSegment :: Applicative f => (a -> f ()) -> Int -> Int -> BinList a -> f ()+traverseSegment f s e xs+  | s > e = pure ()+  | e < 0 = pure ()+  | s >= length xs = pure ()+  | otherwise = traverseSegmentFromTo f (max 0 s) e xs++{-# INLINE traverseSegmentFromTo #-}++traverseSegmentFromTo :: Applicative f => (a -> f ()) -> Int -> Int -> BinList a -> f ()+traverseSegmentFromTo f = go+  where+    go s e (ListNode n l r) =+      let k = 2^(n-1)+      in  if s >= k+             -- Sublist is contained in right portion+             then go (s - k) (e - k) r+             else if e < k+                     -- Sublist is contained in left portion+                     then go s e l+                     -- Sublist is divided in both portions+                     else traverseSegmentFrom f s l *> traverseSegmentTo f (e - k) r+    go _ _ (ListEnd x) = f x++{-# INLINE traverseSegmentFrom #-}++traverseSegmentFrom :: Applicative f => (a -> f ()) -> Int -> BinList a -> f ()+traverseSegmentFrom f = go+  where+    go s (ListNode n l r) =+      let k = 2^(n-1)+      in  if s >= k+             -- Sublist is contained in right portion+             then go (s - k) r+             -- Sublist is divided in both portions, but right+             -- portion is taken entirely+             else go s l *> traverseFull f r+    go _ (ListEnd x) = f x++{-# INLINE traverseSegmentTo #-}++traverseSegmentTo :: Applicative f => (a -> f ()) -> Int -> BinList a -> f ()+traverseSegmentTo f = go+  where+    go e (ListNode n l r) =+      let k = 2^(n-1)+      in  if e < k+             -- Sublist is contained in left portion+             then go e l+             -- Sublist is divided in both portions, but left+             -- portion is taken entirely+             else traverseFull f l *> go (e - k) r+    go _ (ListEnd x) = f x++{-# INLINE traverseFull #-}++traverseFull :: Applicative f => (a -> f ()) -> BinList a -> f ()+traverseFull f = go+  where+    go (ListEnd x) = f x+    go (ListNode _ l r) = go l *> go r++------------------------------------------------+------------------------------------------------+ ----------------------------- -- Show and Functor instances @@ -457,7 +553,5 @@ >       in  fromJust $ >             BL.append (BL.zipWith (+) evensfft oddsfft) >                       (BL.zipWith (-) evensfft oddsfft)--  -}
Data/BinaryList/Serialize.hs view
@@ -52,7 +52,7 @@ --   If you foresee reading only a part of the list, either --   at its beginning or end, an appropiate choice of direction --   will allow you to avoid decoding the full list.-data Direction = FromLeft | FromRight deriving Eq+data Direction = FromLeft | FromRight deriving (Eq,Show)  -- | A binary list encoded, ready to be written in a file or be --   sent over a network. It can be directly translated to a@@ -103,6 +103,7 @@                | FinalResult (BinList a) ByteString                  -- | A decoding error, with an error message and the remaining input.                | DecodingError String ByteString+                 deriving Show  -- | Get the final result of a decoding process, unless it returned an error, in which --   case this error is returned as a 'String'.
bench/Main.hs view
@@ -2,20 +2,32 @@ import Data.BinaryList (BinList) import qualified Data.BinaryList as BL +import Control.Applicative import Control.DeepSeq import qualified Data.Foldable as F +-- criterion import Criterion.Main  instance NFData a => NFData (BinList a) where   rnf xs = F.foldl1 seq xs `seq` () +list1024 :: [Int]+list1024 = [1..1024]++list513 :: [Int]+list513 = [1..513]++blist1024 :: BinList Int+blist1024 = BL.generate 10 id+ main :: IO () main = defaultMain   [ bgroup "1024"-      [ bench "fromList" $ nf (\i -> BL.fromList [1..i]) (1024 :: Int)-      , bench "fromListWithDefault" $ nf (\i -> BL.fromListWithDefault 0 [1..i]) (513 :: Int)+      [ bench "fromList" $ nf (\i -> const BL.fromList i $ list1024) 0+      , bench "fromListWithDefault" $ nf (\i -> BL.fromListWithDefault i list513) 0       , bench "generate" $ nf (\i -> BL.generate i id) 10       , bench "replicate" $ nf (\i -> BL.replicate i (0 :: Int)) 10+      , bench "toListSegment" $ nf (\e -> BL.toListSegment 256 e blist1024) 768         ]     ]
binary-list.cabal view
@@ -1,5 +1,5 @@ name:                binary-list-version:             0.3.2.1+version:             0.3.3.0 synopsis:            Lists of size length a power of two. description:         Implementation of lists whose number of elements is a                      power of two. Binary lists have this property by definition,@@ -30,6 +30,7 @@   other-modules:       Data.BinaryList.Internal   build-depends:       base == 4.*, bytestring, binary >= 0.6.4.0                ,       transformers >= 0.3.0.0+               ,       phantom-state >= 0.2   default-language:    Haskell2010   ghc-options:         -Wall -fno-warn-orphans