|
1 | | -{-# OPTIONS_GHC -fno-warn-incomplete-patterns #-} |
2 | 1 | {-# OPTIONS_HADDOCK prune #-} |
3 | 2 | {-# LANGUAGE Trustworthy #-} |
4 | 3 |
|
@@ -1095,6 +1094,7 @@ splitWith p (Chunk c0 cs0) = comb [] (S.splitWith p c0) cs0 |
1095 | 1094 | comb acc [s] Empty = [revChunks (s:acc)] |
1096 | 1095 | comb acc [s] (Chunk c cs) = comb (s:acc) (S.splitWith p c) cs |
1097 | 1096 | comb acc (s:ss) cs = revChunks (s:acc) : comb [] ss cs |
| 1097 | + comb _ [] _ = error "Strict splitWith returned [] for nonempty input" |
1098 | 1098 | {-# INLINE splitWith #-} |
1099 | 1099 |
|
1100 | 1100 | -- | /O(n)/ Break a 'ByteString' into pieces separated by the byte |
@@ -1122,6 +1122,7 @@ split w (Chunk c0 cs0) = comb [] (S.split w c0) cs0 |
1122 | 1122 | comb acc [s] Empty = [revChunks (s:acc)] |
1123 | 1123 | comb acc [s] (Chunk c cs) = comb (s:acc) (S.split w c) cs |
1124 | 1124 | comb acc (s:ss) cs = revChunks (s:acc) : comb [] ss cs |
| 1125 | + comb _ [] _ = error "Strict split returned [] for nonempty input" |
1125 | 1126 | {-# INLINE split #-} |
1126 | 1127 |
|
1127 | 1128 | -- | The 'group' function takes a ByteString and returns a list of |
@@ -1441,16 +1442,22 @@ zipWith _ Empty _ = [] |
1441 | 1442 | zipWith _ _ Empty = [] |
1442 | 1443 | zipWith f (Chunk a as) (Chunk b bs) = go a as b bs |
1443 | 1444 | where |
1444 | | - go x xs y ys = f (S.unsafeHead x) (S.unsafeHead y) |
1445 | | - : to (S.unsafeTail x) xs (S.unsafeTail y) ys |
1446 | | - |
1447 | | - to x Empty _ _ | S.null x = [] |
1448 | | - to _ _ y Empty | S.null y = [] |
1449 | | - to x xs y ys | not (S.null x) |
1450 | | - && not (S.null y) = go x xs y ys |
1451 | | - to x xs _ (Chunk y' ys) | not (S.null x) = go x xs y' ys |
1452 | | - to _ (Chunk x' xs) y ys | not (S.null y) = go x' xs y ys |
1453 | | - to _ (Chunk x' xs) _ (Chunk y' ys) = go x' xs y' ys |
| 1445 | + -- This loop is written in a slightly awkward way but ensures we |
| 1446 | + -- don't have to allocate any 'Chunk' objects to pass to a recursive |
| 1447 | + -- call. We have in some sense performed SpecConstr manually. |
| 1448 | + go !x xs !y ys = let |
| 1449 | + -- Creating a thunk for reading one byte would |
| 1450 | + -- be wasteful, so we evaluate these eagerly. |
| 1451 | + -- See also #558 for a similar issue with uncons. |
| 1452 | + !xHead = S.unsafeHead x |
| 1453 | + !yHead = S.unsafeHead y |
| 1454 | + in f xHead yHead : to (S.unsafeTail x) xs (S.unsafeTail y) ys |
| 1455 | + |
| 1456 | + to !x xs !y ys |
| 1457 | + | Chunk x' xs' <- chunk x xs |
| 1458 | + , Chunk y' ys' <- chunk y ys |
| 1459 | + = go x' xs' y' ys' |
| 1460 | + | otherwise = [] |
1454 | 1461 |
|
1455 | 1462 | -- | A specialised version of `zipWith` for the common case of a |
1456 | 1463 | -- simultaneous map over two ByteStrings, to build a 3rd. |
|
0 commit comments