Nicolas Pouillard avatar Nicolas Pouillard committed 65d025c

Data.Text.Fusion: move a bang-pattern to make clearer and maybe more effective

Comments (0)

Files changed (1)

Data/Text/Fusion.hs

 length = S.lengthI
 {-# INLINE[0] length #-}
 
+-- | /O(n)/ Returns the number of characters in a text.
+length64 :: Stream Char -> Int64
+length64 (Stream next s0 _len) = loop_length 0 s0
+    where
+      loop_length z s  = case next s of
+                           Done       -> z
+                           Skip    s' -> loop_length z s'
+                           Yield _ s' -> let !z' = z + 1
+                                         in loop_length z' s'
+{-# INLINE[0] length64 #-}
+
+-- ----------------------------------------------------------------------------
+-- * Stream transformations
+
+-- | /O(n)/ 'map' @f @xs is the Stream Char obtained by applying @f@ to each element of
+-- @xs@.
+map :: (Char -> Char) -> Stream Char -> Stream Char
+map f (Stream next0 s0 len) = Stream next s0 len
+    where
+      {-# INLINE next #-}
+      next !s = case next0 s of
+                  Done       -> Done
+                  Skip s'    -> Skip s'
+                  Yield x s' -> Yield (f x) s'
+{-# INLINE [0] map #-}
+
+{-#
+  RULES "STREAM map/map fusion" forall f g s.
+     map f (map g s) = map (\x -> f (g x)) s
+ #-}
+
+-- | /O(n)/ Take a character and place it between each of the
+-- characters of a 'Stream Char'.
+intersperse :: Char -> Stream Char -> Stream Char
+intersperse c (Stream next0 s0 len) = Stream next (s0 :!: Nothing :!: S1) len
+    where
+      {-# INLINE next #-}
+      next (s :!: Nothing :!: S1) = case next0 s of
+        Done       -> Done
+        Skip s'    -> Skip (s' :!: Nothing :!: S1)
+        Yield x s' -> Skip (s' :!: Just x :!: S1)
+      next (s :!: Just x :!: S1)  = Yield x (s :!: Nothing :!: S2)
+      next (s :!: Nothing :!: S2) = case next0 s of
+        Done       -> Done
+        Skip s'    -> Skip    (s' :!: Nothing :!: S2)
+        Yield x s' -> Yield c (s' :!: Just x :!: S1)
+      next _ = internalError "intersperse"
+{-# INLINE [0] intersperse #-}
+
 -- | /O(n)/ Reverse the characters of a string.
 reverse :: Stream Char -> Text
 reverse (Stream next s len0)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.