Data.ByteString: fix lazyness of take, drop & splitAt
authorDon Stewart <dons@cse.unsw.edu.au>
Thu, 5 Oct 2006 01:17:03 +0000 (01:17 +0000)
committerDon Stewart <dons@cse.unsw.edu.au>
Thu, 5 Oct 2006 01:17:03 +0000 (01:17 +0000)
ByteString.Lazy's take, drop and splitAt were too strict when demanding
a byte string. Spotted by Einar Karttunen. Thanks to him and to Bertram
Felgenhauer for explaining the problem and the fix.

Data/ByteString/Lazy.hs

index 80b80ea..92c28a8 100644 (file)
@@ -663,10 +663,10 @@ unfoldr f = LPS . unfoldChunk 32
 -- | /O(n\/c)/ 'take' @n@, applied to a ByteString @xs@, returns the prefix
 -- of @xs@ of length @n@, or @xs@ itself if @n > 'length' xs@.
 take :: Int64 -> ByteString -> ByteString
-take n _ | n < 0 = empty
-take i (LPS ps)  = LPS (take' i ps)
-  where take' _ []     = []
-        take' 0 _      = []
+take i _ | i <= 0 = empty
+take i (LPS ps)   = LPS (take' i ps)
+  where take' 0 _      = []
+        take' _ []     = []
         take' n (x:xs) =
           if n < fromIntegral (P.length x)
             then P.take (fromIntegral n) x : []
@@ -677,8 +677,8 @@ take i (LPS ps)  = LPS (take' i ps)
 drop  :: Int64 -> ByteString -> ByteString
 drop i p | i <= 0 = p
 drop i (LPS ps) = LPS (drop' i ps)
-  where drop' _ []     = []
-        drop' 0 xs     = xs
+  where drop' 0 xs     = xs
+        drop' _ []     = []
         drop' n (x:xs) =
           if n < fromIntegral (P.length x)
             then P.drop (fromIntegral n) x : xs
@@ -688,8 +688,8 @@ drop i (LPS ps) = LPS (drop' i ps)
 splitAt :: Int64 -> ByteString -> (ByteString, ByteString)
 splitAt i p        | i <= 0 = (empty, p)
 splitAt i (LPS ps) = case splitAt' i ps of (a,b) -> (LPS a, LPS b)
-  where splitAt' _ []     = ([], [])
-        splitAt' 0 xs     = ([], xs)
+  where splitAt' 0 xs     = ([], xs)
+        splitAt' _ []     = ([], [])
         splitAt' n (x:xs) =
           if n < fromIntegral (P.length x)
             then (P.take (fromIntegral n) x : [],