Commits

Bryan O'Sullivan committed 840e93d

Add isSingleton function.

  • Participants
  • Parent commits 083a7f9

Comments (0)

Files changed (2)

File Data/Text.hs

     S.null (stream t) = null t
  #-}
 
+-- | /O(1)/ Tests whether a 'Text' contains exactly one character.
+-- Subject to fusion.
+isSingleton :: Text -> Bool
+isSingleton = S.isSingleton . stream
+{-# INLINE isSingleton #-}
+
 -- | /O(n)/ Returns the number of characters in a 'Text'.
 -- Subject to fusion.
 length :: Text -> Int
 -- In (unlikely) bad cases, this function's time complexity
 -- degenerates towards /O(n*m)/.
 split :: Text -> Text -> [Text]
-split pat src@(Text arr off len)
-    | null pat  = emptyError "split"
-    | l == 1    = splitWith (== unsafeHead pat) src
-    | otherwise = go 0 (indices pat src)
+split pat@(Text _ _ l) src@(Text arr off len)
+    | l <= 0          = emptyError "split"
+    | isSingleton pat = splitWith (== unsafeHead pat) src
+    | otherwise       = go 0 (indices pat src)
   where
-    l            =  length pat
     go !s (x:xs) =  textP arr (s+off) (x-s) : go (x+l) xs
     go  s _      = [textP arr (s+off) (len-s)]
 {-# INLINE [1] split #-}
            -> Text              -- ^ Text to split on
            -> Text              -- ^ Input text
            -> [Text]
-splitTimes k pat src@(Text arr off len)
-    | null pat  = emptyError "splitTimes"
+splitTimes k pat@(Text _ _ l) src@(Text arr off len)
+    | l <= 0    = emptyError "splitTimes"
     | otherwise = go 0 0 (indices pat src)
   where
     go !s !i _  | i >= k = [textP arr (s+off) (len-s)]
     go !s  _ []          = [textP arr (s+off) (len-s)]
     go !s !i (x:xs)      =  textP arr (s+off) (x-s) : go (x+l) (i+1) xs
-    l                    =  length pat
 {-# INLINE splitTimes #-}
 
 -- | /O(m+n)/ Break a 'Text' into pieces at most @k@ times, like

File Data/Text/Fusion/Common.hs

     , init
     , null
     , lengthI
+    , isSingleton
 
     -- * Transformations
     , map
                        Skip s'   -> loop_null s'
 {-# INLINE[0] null #-}
 
--- | /O(n)/ Returns the number of characters in a text.
+-- | /O(n)/ Returns the number of characters in a string.
 lengthI :: Integral a => Stream Char -> a
 lengthI (Stream next s0 _len) = loop_length 0 s0
     where
                            Yield _ s' -> loop_length (z + 1) s'
 {-# INLINE[0] lengthI #-}
 
+-- | /O(n)/ Indicate whether a string contains exactly one element.
+isSingleton :: Stream Char -> Bool
+isSingleton (Stream next s0 _len) = loop 0 s0
+    where
+      loop !z s  = case next s of
+                     Done            -> z == (1::Int)
+                     Skip    s'      -> loop z s'
+                     Yield _ s'
+                         | z >= 1    -> False
+                         | otherwise -> loop (z+1) s'
+{-# INLINE[0] isSingleton #-}
+
 -- ----------------------------------------------------------------------------
 -- * Stream transformations