on master help sign in
Add isSingleton function.

--HG-- extra : convert_revision : bc24f094b23cc283b4319c15cd26c1a0f7a409fd

commitf8e8603c7fdea8bc4372bc8e1f7d75bcf41510df authorBryan O'Sullivan <bos@serpentine.com> dateTue 6 Oct 2009, 18:37 (17 years ago) parent0401b67
2 files changed+26−9
Data/Text.hs+12−8 Data/Text/Fusion/Common.hs+14−1
Data/Text.hs+12−8
@@ -368,6 +368,12 @@ null (Text _arr _off len) = assert (len >= 0) $ len <= 0
368368 S.null (stream t) = null t
369369 #-}
370370
371+-- | /O(1)/ Tests whether a 'Text' contains exactly one character.
372+-- Subject to fusion.
373+isSingleton :: Text -> Bool
374+isSingleton = S.isSingleton . stream
375+{-# INLINE isSingleton #-}
376+
371377-- | /O(n)/ Returns the number of characters in a 'Text'.
372378-- Subject to fusion.
373379length :: Text -> Int
@@ -916,12 +922,11 @@ tails t | null t = [empty]
916922-- In (unlikely) bad cases, this function's time complexity
917923-- degenerates towards /O(n*m)/.
918924split :: Text -> Text -> [Text]
919−split pat src@(Text arr off len)
920− | null pat = emptyError "split"
921− | l == 1 = splitWith (== unsafeHead pat) src
922− | otherwise = go 0 (indices pat src)
925+split pat@(Text _ _ l) src@(Text arr off len)
926+ | l <= 0 = emptyError "split"
927+ | isSingleton pat = splitWith (== unsafeHead pat) src
928+ | otherwise = go 0 (indices pat src)
923929 where
924− l = length pat
925930 go !s (x:xs) = textP arr (s+off) (x-s) : go (x+l) xs
926931 go s _ = [textP arr (s+off) (len-s)]
927932{-# INLINE [1] split #-}
@@ -955,14 +960,13 @@ splitTimes :: Int -- ^ Maximum number of times to split
955960 -> Text -- ^ Text to split on
956961 -> Text -- ^ Input text
957962 -> [Text]
958−splitTimes k pat src@(Text arr off len)
959− | null pat = emptyError "splitTimes"
963+splitTimes k pat@(Text _ _ l) src@(Text arr off len)
964+ | l <= 0 = emptyError "splitTimes"
960965 | otherwise = go 0 0 (indices pat src)
961966 where
962967 go !s !i _ | i >= k = [textP arr (s+off) (len-s)]
963968 go !s _ [] = [textP arr (s+off) (len-s)]
964969 go !s !i (x:xs) = textP arr (s+off) (x-s) : go (x+l) (i+1) xs
965− l = length pat
966970{-# INLINE splitTimes #-}
967971
968972-- | /O(m+n)/ Break a 'Text' into pieces at most @k@ times, like
Data/Text/Fusion/Common.hs+14−1
@@ -29,6 +29,7 @@ module Data.Text.Fusion.Common
2929 , init
3030 , null
3131 , lengthI
32+ , isSingleton
3233
3334 -- * Transformations
3435 , map
@@ -255,7 +256,7 @@ null (Stream next s0 _len) = loop_null s0
255256 Skip s' -> loop_null s'
256257{-# INLINE[0] null #-}
257258
258−-- | /O(n)/ Returns the number of characters in a text.
259+-- | /O(n)/ Returns the number of characters in a string.
259260lengthI :: Integral a => Stream Char -> a
260261lengthI (Stream next s0 _len) = loop_length 0 s0
261262 where
@@ -265,6 +266,18 @@ lengthI (Stream next s0 _len) = loop_length 0 s0
265266 Yield _ s' -> loop_length (z + 1) s'
266267{-# INLINE[0] lengthI #-}
267268
269+-- | /O(n)/ Indicate whether a string contains exactly one element.
270+isSingleton :: Stream Char -> Bool
271+isSingleton (Stream next s0 _len) = loop 0 s0
272+ where
273+ loop !z s = case next s of
274+ Done -> z == (1::Int)
275+ Skip s' -> loop z s'
276+ Yield _ s'
277+ | z >= 1 -> False
278+ | otherwise -> loop (z+1) s'
279+{-# INLINE[0] isSingleton #-}
280+
268281-- ----------------------------------------------------------------------------
269282-- * Stream transformations
270283