on master help sign in
Refactor the helper function from break up to the top level.
44ea38eBryan O'Sullivan
Data/Text/Lazy.hs+15−9
@@ -177,6 +177,7 @@ import qualified Data.Text.Internal as T
177import qualified Data.Text.Fusion.Common as S
177import qualified Data.Text.Fusion.Common as S
178import qualified Data.Text.Unsafe as T
178import qualified Data.Text.Unsafe as T
179import qualified Data.Text.Lazy.Fusion as S
179import qualified Data.Text.Lazy.Fusion as S
180+import Data.Text.Fusion.Internal (PairS(..))
180import Data.Text.Lazy.Fusion (stream, unstream)
181import Data.Text.Lazy.Fusion (stream, unstream)
181import Data.Text.Lazy.Internal (Text(..), chunk, empty, foldlChunks, foldrChunks)
182import Data.Text.Lazy.Internal (Text(..), chunk, empty, foldlChunks, foldrChunks)
182import Data.Text.Internal (textP)
183import Data.Text.Internal (textP)
@@ -813,6 +814,18 @@ splitAt = loop
813 in (Chunk t ts', ts'')
814 in (Chunk t ts', ts'')
814 where len = fromIntegral (T.length t)
815 where len = fromIntegral (T.length t)
815
816
817+-- | /O(n)/ 'splitAtWord' @n t@ returns a strict pair whose first
818+-- element is a prefix of @t@ whose chunks contain @n@ 'Word16'
819+-- values, and whose second is the remainder of the string.
820+splitAtWord :: Int64 -> Text -> PairS Text Text
821+splitAtWord _ Empty = empty :*: empty
822+splitAtWord x (Chunk c@(T.Text arr off len) cs)
823+ | y >= len = let h :*: t = splitAtWord (x-fromIntegral len) cs
824+ in Chunk c h :*: t
825+ | otherwise = chunk (textP arr off y) empty :*:
826+ chunk (textP arr (off+y) (len-y)) cs
827+ where y = fromIntegral x
828+
816-- | /O(n+m)/ Find the first instance of @needle@ (which must be
829-- | /O(n+m)/ Find the first instance of @needle@ (which must be
817-- non-'null') in @haystack@. The first element of the returned tuple
830-- non-'null') in @haystack@. The first element of the returned tuple
818-- is the prefix of @haystack@ before @needle@ is matched. The second
831-- is the prefix of @haystack@ before @needle@ is matched. The second
@@ -839,15 +852,8 @@ break pat src
839 | null pat = emptyError "break"
852 | null pat = emptyError "break"
840 | otherwise = case indices pat src of
853 | otherwise = case indices pat src of
841 [] -> (src, empty)
854 [] -> (src, empty)
842− (x:_) -> go x src
855+ (x:_) -> let h :*: t = splitAtWord x src
843− where
844− go _ Empty = (empty, empty)
845− go x (Chunk c@(T.Text arr off len) cs)
846− | y >= len = let (h,t) = go (x-fromIntegral len) cs
847− in (Chunk c h, t)
856+ in (h, t)
848− | otherwise = (chunk (textP arr off y) empty,
849− chunk (textP arr (off+y) (len-y)) cs)
850− where y = fromIntegral x
851
857
852-- | /O(n)/ 'breakBy' is like 'spanBy', but the prefix returned is over
858-- | /O(n)/ 'breakBy' is like 'spanBy', but the prefix returned is over
853-- elements that fail the predicate @p@.
859-- elements that fail the predicate @p@.