@@ -96,8 +96,8 @@ module Data.Text
96 , takeWhile
96 , takeWhile
97 , dropWhile
97 , dropWhile
100− -- , break
100+ , break
101 -- , group
101 -- , group
102 -- , groupBy
102 -- , groupBy
@@ -148,7 +148,7 @@ import Prelude (Char, Bool, Functor(..), Int, Maybe(..), String,
148 Show, showsPrec,
148 Show, showsPrec,
149 Read, readsPrec,
149 Read, readsPrec,
150 (&&), (||), (+), (-), (<), (>), (<=), (>=), (.),
150 (&&), (||), (+), (-), (<), (>), (<=), (>=), (.),
151− return, otherwise)
151+ not, return, otherwise)
152import Data.Char (isSpace)
152import Data.Char (isSpace)
153import Control.Monad.ST (ST)
153import Control.Monad.ST (ST)
154import qualified Data.Text.Array as A
154import qualified Data.Text.Array as A
@@ -634,7 +634,7 @@ dropWhile p (Text arr off len) = loop off 0
636-- | /O(n)/ 'splitAt' @n t@ returns a pair whose first element is a
636-- | /O(n)/ 'splitAt' @n t@ returns a pair whose first element is a
637−-- prefix of @t@ of length @n@ and second element is the remainder of
637+-- prefix of @t@ of length @n@, and whose second is the remainder of
638-- the string. It is equivalent to @('take' n t, 'drop' n t)@.
638-- the string. It is equivalent to @('take' n t, 'drop' n t)@.
639splitAt :: Int -> Text -> (Text, Text)
639splitAt :: Int -> Text -> (Text, Text)
640splitAt n t@(Text arr off len)
640splitAt n t@(Text arr off len)
@@ -644,11 +644,32 @@ splitAt n t@(Text arr off len)
644 where k = loop off 0
644 where k = loop off 0
645 end = off + len
645 end = off + len
646 loop !i !count
646 loop !i !count
647− | i >= end || count >= n = i - off
647+ | i >= end || count >= n = i - off
648− | otherwise = loop (i+d) (count+1)
648+ | otherwise = loop (i+d) (count+1)
649− where d = iter_ arr i
649+ where d = iter_ arr i
650{-# INLINE splitAt #-}
650{-# INLINE splitAt #-}
652+-- | /O(n)/ 'span', applied to a predicate @p@ and text @t@, returns a
653+-- pair whose first element is the longest prefix (possibly empty) of
654+-- @t@ of elements that satisfy @p@, and whose second is the remainder
656+span :: (Char -> Bool) -> Text -> (Text, Text)
657+span p t@(Text arr off len)
658+ | k == 0 = (empty, t)
659+ | k == len = (t, empty)
660+ | otherwise = (Text arr off k, Text arr (off+k) (len-k))
661+ where k = loop off 0
662+ loop !i !l | l >= len || not (p c) = l
663+ | otherwise = loop (i+d) (l+d)
664+ where (c,d) = iter arr i
667+-- | /O(n)/ 'break' is like 'span', but the prefix returned is over
668+-- elements that fail the predicate @p@.
669+break :: (Char -> Bool) -> Text -> (Text, Text)
670+break p = span (not . p)
652-- | /O(n)/ Return all initial segments of the given 'Text', shortest
673-- | /O(n)/ Return all initial segments of the given 'Text', shortest
654inits :: Text -> [Text]
675inits :: Text -> [Text]