span package:text

O(n) span, applied to a predicate p and text t, returns a pair whose first element is the longest prefix (possibly empty) of t of elements that satisfy p, and whose second is the remainder of the text.
>>> T.span (=='0') "000AB"
("000","AB")
O(length of suffix) spanEndM, applied to a monadic predicate p, a text t, returns a pair (t1, t2) where t2 is the longest suffix of t whose elements satisfy p, and t1 is the remainder of the text.
>>> T.spanEndM (\c -> state $ \i -> (fromEnum c == i, i-1)) "tuvxyz" `runState` 122
(("tuv","xyz"),118)
spanEndM p . reverse = fmap (bimap reverse reverse) . spanM p
O(length of prefix) spanM, applied to a monadic predicate p, a text t, returns a pair (t1, t2) where t1 is the longest prefix of t whose elements satisfy p, and t2 is the remainder of the text.
>>> T.spanM (\c -> state $ \i -> (fromEnum c == i, i+1)) "abcefg" `runState` 97
(("abc","efg"),101)
span is spanM specialized to Identity:
-- for all p :: Char -> Bool
span p = runIdentity . spanM (pure . p)
For the sake of performance this function does not check that a char is in ASCII range; it is a responsibility of p.