Commits

Bryan O'Sullivan  committed 792d566

Add an unstreamed version of takeWhile

  • Participants
  • Parent commits 7ed9330

Comments (0)

Files changed (2)

File Data/Text.hs

     unstream (S.drop n (stream t)) = drop n t
   #-}
 
--- | /O(n)/ 'takeWhile', applied to a predicate @p@ and a 'Text', returns the
--- longest prefix (possibly empty) of elements that satisfy @p@.
+-- | /O(n)/ 'takeWhile', applied to a predicate @p@ and a 'Text', returns
+-- the longest prefix (possibly empty) of elements that satisfy @p@.
+-- This function is subject to array fusion.
 takeWhile :: (Char -> Bool) -> Text -> Text
-takeWhile p t = unstream (S.takeWhile p (stream t))
-{-# INLINE takeWhile #-}
+takeWhile p t@(Text arr off len) = loop off 0
+  where loop !i !l | l >= len    = t
+                   | p c         = loop (i+d) (l+d)
+                   | otherwise   = Text arr off l
+            where (c,d)          = iter arr i
+{-# INLINE [1] takeWhile #-}
+
+{-# RULES
+"TEXT takeWhile -> fused" [~1] forall p t.
+    takeWhile p t = unstream (S.takeWhile p (stream t))
+"TEXT takeWhile -> unfused" [1] forall p t.
+    unstream (S.takeWhile p (stream t)) = takeWhile p t
+  #-}
 
 -- | /O(n)/ 'dropWhile' @p@ @xs@ returns the suffix remaining after
 -- 'takeWhile' @p@ @xs@.

File tests/Properties.hs

 prop_take n          = L.take n      `eqP` (unpack . T.take n)
 prop_drop n          = L.drop n      `eqP` (unpack . T.drop n)
 prop_takeWhile p     = L.takeWhile p `eqP` (unpack . T.takeWhile p)
+prop_takeWhileS p    = L.takeWhile p `eqP` (unpack . unstream . S.takeWhile p . stream)
 prop_dropWhile p     = L.dropWhile p `eqP` (unpack . T.dropWhile p)
 prop_inits           = L.inits       `eqP` (map unpack . T.inits)
 prop_tails           = L.tails       `eqP` (map unpack . T.tails)
   ("prop_take", mytest prop_take),
   ("prop_drop", mytest prop_drop),
   ("prop_takeWhile", mytest prop_takeWhile),
+  ("prop_takeWhileS", mytest prop_takeWhileS),
   ("prop_dropWhile", mytest prop_dropWhile),
   ("prop_inits", mytest prop_inits),
   ("prop_tails", mytest prop_tails),