packages feed

binary-list 0.2.0.4 → 0.3.0.0

raw patch · 3 files changed

+81/−53 lines, 3 filesdep +transformersPVP ok

version bump matches the API change (PVP)

Dependencies added: transformers

API changes (from Hackage documentation)

- Data.BinaryList: maximum :: Ord a => BinList a -> a
- Data.BinaryList: minimum :: Ord a => BinList a -> a
- Data.BinaryList: toList :: BinList a -> [a]
+ Data.BinaryList: instance Foldable BinList
+ Data.BinaryList: instance Traversable BinList
+ Data.BinaryList: replicateA :: Applicative f => Int -> f a -> f (BinList a)
+ Data.BinaryList: replicateAR :: Applicative f => Int -> f a -> f (BinList a)
- Data.BinaryList: fold :: (a -> a -> a) -> BinList a -> a
+ Data.BinaryList: fold :: Foldable t => forall m. Monoid m => t m -> m

Files

Data/BinaryList.hs view
@@ -3,7 +3,9 @@ --   This data structure is efficient for some computations like: -- -- * Splitting a list in half.+-- -- * Appending two lists of the same length.+-- -- * Extracting an element from the list. -- --   All the functions exported are total except for 'fromListWithDefault'.@@ -16,6 +18,10 @@ -- > import Data.BinaryList (BinList) -- > import qualified Data.BinaryList as BL --+--   Remember that binary lists are an instance of the 'Foldable' and 'Traversable'+--   classes. If you are missing a function here, look for functions using those+--   instances.+-- module Data.BinaryList (     -- * Type     BinList@@ -23,14 +29,14 @@   , singleton   , append   , replicate+  , replicateA+  , replicateAR     -- * Queries   , lengthIndex   , length   , lookup   , head   , last-  , minimum-  , maximum     -- * Decontruction   , split   , fold@@ -45,17 +51,18 @@     -- * Lists   , fromList   , fromListWithDefault-  , toList   ) where -import Prelude hiding ( length,lookup,replicate,head,last,zip,unzip,zipWith,reverse-                      , minimum, maximum-                        )+import Prelude hiding ( length,lookup,replicate,head,last,zip,unzip,zipWith,reverse,foldr1 ) import qualified Prelude import Foreign.Storable (sizeOf) import Data.List (find) import Data.BinaryList.Internal-+import Control.Applicative (Applicative (..),(<$>))+import Control.Applicative.Backwards+import Data.Monoid (mappend)+import Data.Foldable (Foldable (..),toList)+import Data.Traversable (Traversable (..))  -- | /O(1)/. Build a list with a single element. singleton :: a -> BinList a@@ -104,21 +111,40 @@ -- | /O(log n)/. Calling @replicate n x@ builds a binary list with --   @2^n@ occurences of @x@. replicate :: Int -> a -> BinList a-replicate 0 x = ListEnd x-replicate n x =-  let b = replicate (n-1) x -- Both branches of the binary list-  in  ListNode n b b -- Note that both branches are the same shared object+replicate n x = go n+  where+    go 0 = ListEnd x+    go i = let b = go (i-1) -- Both branches of the binary list+           in  ListNode i b b -- Note that both branches are the same shared object  {-# RULES       "Data.BinaryList: fmap/replicate"-         forall f n x. fmap f (replicate n x) = replicate n (f x)+         forall f n x . fmap f (replicate n x) = replicate n (f x)   #-} --- | Fold a binary list using an operator.-fold :: (a -> a -> a) -> BinList a -> a-fold f (ListNode _ l r) = f (fold f l) (fold f r)-fold _ (ListEnd x) = x+-- | Calling @replicateA n f@ builds a binary list collecting the results of+--   executing @2^n@ times the applicative action @f@.+replicateA :: Applicative f => Int -> f a -> f (BinList a)+replicateA n f = go n+  where+    go 0 = ListEnd <$> f+    go i = let b = go (i-1)+           in  ListNode <$> pure i <*> b <*> b +-- | The same as 'replicateA', but the actions are executed in reversed order.+replicateAR :: Applicative f => Int -> f a -> f (BinList a)+replicateAR n = forwards . replicateA n . Backwards++{-# RULES+      "Data.BinaryList: fmap reverse/replicateA"+         forall i f . fmap reverse (replicateA  i f) = replicateAR i f+  #-}++{-# RULES+      "Data.BinaryList: fmap reverse/replicateAR"+         forall i f . fmap reverse (replicateAR i f) = replicateA  i f+  #-}+ -- | /O(log n)/. Get the first element of a binary list. head :: BinList a -> a head (ListNode _ l _) = head l@@ -139,16 +165,6 @@          forall xs. reverse (reverse xs) = xs   #-} --- | /O(n)/. Retrieves the minimum element of a binary list.-minimum :: Ord a => BinList a -> a-minimum (ListEnd x) = x-minimum (ListNode _ l r) = min (minimum l) (minimum r)---- | /O(n)/. Retrieves the maximum element of a binary list.-maximum :: Ord a => BinList a -> a-maximum (ListEnd x) = x-maximum (ListNode _ l r) = max (maximum l) (maximum r)- ------------------------------ -- Transformations with tuples @@ -273,13 +289,6 @@              then ListNode n (go xs l m) (replicate m e)              else ListNode n (fromListBuilder ys m) (go zs (l - l') m) --- | /O(n)/. Build a linked list from a binary list.-toList :: BinList a -> [a]-toList = go []-  where-    go xs (ListNode _ l r) = go (go xs r) l-    go xs (ListEnd x) = x : xs- ----------------------------- -- Show and Functor instances @@ -289,3 +298,18 @@ instance Functor BinList where   fmap f (ListNode n l r) = ListNode n (fmap f l) (fmap f r)   fmap f (ListEnd x) = ListEnd $ f x++instance Foldable BinList where+  -- Folding+  foldr1 f = go+    where+      go (ListEnd x) = x+      go (ListNode _ l r) = f (go l) (go r)+  --+  fold = foldr1 mappend+  foldl1 = foldr1+  foldMap f = fold . fmap f++instance Traversable BinList where+  sequenceA (ListEnd f) = ListEnd <$> f+  sequenceA (ListNode n l r) = ListNode <$> pure n <*> sequenceA l <*> sequenceA r
Data/BinaryList/Serialize.hs view
@@ -19,7 +19,8 @@    , encodedFromByteString    ) where -import Prelude hiding (reverse)+import Prelude hiding (foldr,foldl)+import Data.Foldable (foldr,foldl) -- Binary lists import Data.BinaryList.Internal import Data.BinaryList@@ -29,8 +30,6 @@ import Data.Binary.Get -- Bytestrings import Data.ByteString.Lazy (ByteString)--- Utils-import Control.Monad (replicateM)  -- | Encode a binary list using the 'Binary' instance of --   its elements.@@ -72,8 +71,8 @@ encodeBinList :: (a -> Put) -> Direction -> BinList a -> EncodedBinList encodeBinList f d xs = EncodedBinList d (lengthIndex xs) $   if d == FromLeft-     then runPut $ foldr (\x y -> f x >> y) (return ()) $ toList xs-     else runPut $ foldl (\y x -> f x >> y) (return ()) $ toList xs+     then runPut $ foldr (\x y -> f x >> y) (return ()) xs+     else runPut $ foldl (\y x -> f x >> y) (return ()) xs  -- | A binary list decoded, from where you can extract a binary list. If the --   decoding process fails in some point, you still will be able to retrieve@@ -119,16 +118,23 @@     Left (r,_,err) -> DecodingError err r     Right (r,_,x) -> go r (ListEnd x)   where-    -- | To avoid looking at the direction in each recursive step,-    --   we provide a function to append newly read data with the-    --   accumulated binary list depending on the direction. Since the-    --   new data is of the same size as the accumulated binary list,-    --   we can append them safely just by using 'ListNode'.+    -- | Function to get binary trees using the supplied 'Get' value.+    --   The order of the elements depends on the encoding direction.     --+    -- getBinList :: Int -> Get (BinList a)+    getBinList =+       case d of+         FromLeft -> \i -> replicateA  i f+         _        -> \i -> replicateAR i f++    -- | Function to append two binary lists of given length index,+    --   where the order of appending depends on the encoding+    --   direction.+    --     -- recAppend :: Int -> BinList a -> BinList a -> BinList a-    recAppend i = case d of-       FromLeft    -> ListNode (i+1)-       _ -> \xs ys -> ListNode (i+1) (reverse ys) xs+    recAppend = case d of+       FromLeft -> \i ->        ListNode (i+1)+       _        -> \i -> flip $ ListNode (i+1)      -- | Recursive decoding function.     --@@ -143,14 +149,11 @@               -- Otherwise, we read another chunk of data of the same size of               -- the already decoded data, prepending the accumulated data as               -- a partial result.-              else PartialResult xs $ case runGetOrFail (replicateM (2^i) f) input of+              else PartialResult xs $ case runGetOrFail (getBinList i) input of                      -- In case of error, we return a decoding error.                      Left (r,_,err) -> DecodingError err r-                     Right (r,_,list) ->-                       let -- Otherwise, we build a new binary list with the collected-                           -- new data.-                           ys = fromListBuilder list i-                           -- The new list is appended with the accumulated list and fed+                     Right (r,_,ys) ->+                       let -- The new list is appended with the accumulated list and fed                            -- to the next recursion step.                        in  go r $ recAppend i xs ys 
binary-list.cabal view
@@ -1,5 +1,5 @@ name:                binary-list-version:             0.2.0.4+version:             0.3.0.0 synopsis:            Lists of size length a power of two. description:         Some algorithmic problems work only when the input list                      has length a power of two. This library provides with a@@ -17,6 +17,7 @@   exposed-modules:     Data.BinaryList, Data.BinaryList.Serialize   other-modules:       Data.BinaryList.Internal   build-depends:       base == 4.*, bytestring, binary >= 0.6.4.0+               ,       transformers >= 0.3.0.0   default-language:    Haskell2010   ghc-options:         -Wall -fno-warn-orphans