@@ -145,6 +145,8 @@ module Data.ByteString.Lazy (
145145 groupBy ,
146146 inits ,
147147 tails ,
148+ initsNE ,
149+ tailsNE ,
148150 stripPrefix ,
149151 stripSuffix ,
150152
@@ -228,6 +230,8 @@ import Prelude hiding
228230 ,getContents ,getLine ,putStr ,putStrLn ,zip ,zipWith ,unzip ,notElem )
229231
230232import qualified Data.List as List
233+ import qualified Data.List.NonEmpty as NE
234+ import Data.List.NonEmpty (NonEmpty (.. ))
231235import qualified Data.Bifunctor as BF
232236import qualified Data.ByteString as P (ByteString ) -- type name only
233237import qualified Data.ByteString as S -- S for strict (hmm...)
@@ -384,7 +388,7 @@ last (Chunk c0 cs0) = go c0 cs0
384388 go _ (Chunk c cs) = go c cs
385389-- XXX Don't inline this. Something breaks with 6.8.2 (haven't investigated yet)
386390
387- -- | /O(n\/c)/ Return all the elements of a 'ByteString' except the last one.
391+ -- | /O(n\/c)/ Returns all the elements of a 'ByteString' except the last one.
388392--
389393-- This is a partial function, consider using 'unsnoc' instead.
390394init :: HasCallStack => ByteString -> ByteString
@@ -1433,19 +1437,39 @@ unzip ls = (pack (List.map fst ls), pack (List.map snd ls))
14331437-- ---------------------------------------------------------------------
14341438-- Special lists
14351439
1436- -- | /O(n)/ Return all initial segments of the given 'ByteString', shortest first.
1440+ -- | Returns all initial segments of the given 'ByteString', shortest first.
14371441inits :: ByteString -> [ByteString ]
1438- inits = (Empty : ) . inits'
1439- where inits' Empty = []
1440- inits' (Chunk c cs) = List. map (`Chunk ` Empty ) (List. drop 1 (S. inits c))
1441- ++ List. map (Chunk c) (inits' cs)
1442+ -- see Note [Avoid NonEmpty combinators] in Data.ByteString
1443+ inits bs = NE. toList $! initsNE bs
14421444
1443- -- | /O(n)/ Return all final segments of the given 'ByteString', longest first.
1445+ -- | Returns all initial segments of the given 'ByteString', shortest first.
1446+ --
1447+ -- @since 0.11.4.0
1448+ initsNE :: ByteString -> NonEmpty ByteString
1449+ -- see Note [Avoid NonEmpty combinators] in Data.ByteString
1450+ initsNE = (Empty :| ) . inits' id
1451+ where
1452+ inits' :: (ByteString -> ByteString ) -> ByteString -> [ByteString ]
1453+ -- inits' f bs === map f (tail (inits bs))
1454+ inits' _ Empty = []
1455+ inits' f (Chunk c@ (S. BS x len) cs)
1456+ = [f (S. BS x n `Chunk ` Empty ) | n <- [1 .. len]]
1457+ ++ inits' (f . Chunk c) cs
1458+
1459+ -- | /O(n)/ Returns all final segments of the given 'ByteString', longest first.
14441460tails :: ByteString -> [ByteString ]
1445- tails Empty = [Empty ]
1446- tails cs@ (Chunk c cs')
1447- | S. length c == 1 = cs : tails cs'
1448- | otherwise = cs : tails (Chunk (S. unsafeTail c) cs')
1461+ -- see Note [Avoid NonEmpty combinators] in Data.ByteString
1462+ tails bs = NE. toList $! tailsNE bs
1463+
1464+ -- | /O(n)/ Returns all final segments of the given 'ByteString', longest first.
1465+ --
1466+ -- @since 0.11.4.0
1467+ tailsNE :: ByteString -> NonEmpty ByteString
1468+ -- see Note [Avoid NonEmpty combinators] in Data.ByteString
1469+ tailsNE bs = case uncons bs of
1470+ Nothing -> Empty :| []
1471+ Just (_, tl) -> bs :| tails tl
1472+
14491473
14501474-- ---------------------------------------------------------------------
14511475-- Low level constructors
0 commit comments