on master help sign in
rules and inlines
4e9f934Luigy Leon
Data/Text.hs+177−138
@@ -224,7 +224,7 @@ import qualified Data.Text.Internal.Fusion.Common as S
224import Data.Text.Encoding (decodeUtf8', encodeUtf8)
224import Data.Text.Encoding (decodeUtf8', encodeUtf8)
225import Data.Text.Internal.Fusion (stream, reverseStream, unstream)
225import Data.Text.Internal.Fusion (stream, reverseStream, unstream)
226-- import Data.Text.Internal.Private (span_)
226-- import Data.Text.Internal.Private (span_)
227−import Data.Text.Internal (Text(..), empty, firstf, mul, safe, text)
227+import Data.Text.Internal (Text(..), empty, empty_, firstf, mul, safe, text)
228-- import Data.Text.Show (singleton, unpack, unpackCString#)
228-- import Data.Text.Show (singleton, unpack, unpackCString#)
229import qualified Prelude as P
229import qualified Prelude as P
230import Data.Text.Unsafe (Iter(..), iter, iter_, lengthWord16, reverseIter,
230import Data.Text.Unsafe (Iter(..), iter, iter_, lengthWord16, reverseIter,
@@ -253,19 +253,44 @@ import qualified Data.JSString.Internal.Fusion as SJS
253import qualified Data.JSString.Internal.Fusion.Common as SJS
253import qualified Data.JSString.Internal.Fusion.Common as SJS
254import Data.Coerce
254import Data.Coerce
255import GHC.Exts (Addr#)
255import GHC.Exts (Addr#)
256+import qualified GHC.CString as GHC
256
257
257unpack :: Text -> String
258unpack :: Text -> String
258unpack = coerce JSS.unpack
259unpack = coerce JSS.unpack
260+{-# INLINE [1] unpack #-}
259
261
260singleton :: Char -> Text
262singleton :: Char -> Text
261singleton = coerce JSS.singleton
263singleton = coerce JSS.singleton
262{-# INLINE [1] singleton #-}
264{-# INLINE [1] singleton #-}
263
265
266+{-# RULES
267+"JSSTRING singleton -> fused" [~1] forall a.
268+ singleton a = unstream (S.singleton (safe a))
269+"JSSTRING singleton -> unfused" [1] forall a.
270+ unstream (S.singleton (safe a)) = singleton a
271+ #-}
264
272
265-- | /O(n)/ Convert a literal string into a JSString. Subject to fusion.
273-- | /O(n)/ Convert a literal string into a JSString. Subject to fusion.
266unpackCString# :: Addr# -> Text
274unpackCString# :: Addr# -> Text
267unpackCString# addr# = Text $ SJS.unstream (SJS.streamCString# addr#)
275unpackCString# addr# = Text $ SJS.unstream (SJS.streamCString# addr#)
268{-# NOINLINE unpackCString# #-}
276{-# NOINLINE unpackCString# #-}
277+
278+{-# RULES "TEXT literal" forall a.
279+ unstream (S.map safe (S.streamList (GHC.unpackCString# a)))
280+ = unpackCString# a #-}
281+
282+{-# RULES "TEXT literal UTF8" [1] forall a.
283+ unstream (S.map safe (S.streamList (GHC.unpackCStringUtf8# a)))
284+ = unpackCString# a #-}
285+
286+{-# RULES "TEXT empty literal" [1]
287+ unstream (S.map safe (S.streamList []))
288+ = empty_ #-}
289+
290+{-# RULES "TEXT singleton literal" [1] forall a.
291+ unstream (S.map safe (S.streamList [a]))
292+ = singleton a #-}
293+
269---------------------------------------------------------------------
294---------------------------------------------------------------------
270
295
271-- $strict
296-- $strict
@@ -494,12 +519,12 @@ append = coerce JSS.append
494-- return arr
519-- return arr
495{-# NOINLINE append #-}
520{-# NOINLINE append #-}
496
521
497−-- {-# RULES
522+{-# RULES
498−-- "TEXT append -> fused" [~1] forall t1 t2.
523+"TEXT append -> fused" [~1] forall t1 t2.
499−-- append t1 t2 = unstream (S.append (stream t1) (stream t2))
524+ append t1 t2 = unstream (S.append (stream t1) (stream t2))
500−-- "TEXT append -> unfused" [1] forall t1 t2.
525+"TEXT append -> unfused" [1] forall t1 t2.
501−-- unstream (S.append (stream t1) (stream t2)) = append t1 t2
526+ unstream (S.append (stream t1) (stream t2)) = append t1 t2
502−-- #-}
527+ #-}
503
528
504-- | /O(1)/ Returns the first character of a 'Text', which must be
529-- | /O(1)/ Returns the first character of a 'Text', which must be
505-- non-empty. Subject to fusion.
530-- non-empty. Subject to fusion.
@@ -534,12 +559,12 @@ last = coerce JSS.last
534-- n0 = A.unsafeIndex arr (off+len-2)
559-- n0 = A.unsafeIndex arr (off+len-2)
535{-# INLINE [1] last #-}
560{-# INLINE [1] last #-}
536
561
537−-- {-# RULES
562+{-# RULES
538−-- "TEXT last -> fused" [~1] forall t.
563+"TEXT last -> fused" [~1] forall t.
539−-- last t = S.last (stream t)
564+ last t = S.last (stream t)
540−-- "TEXT last -> unfused" [1] forall t.
565+"TEXT last -> unfused" [1] forall t.
541−-- S.last (stream t) = last t
566+ S.last (stream t) = last t
542−-- #-}
567+ #-}
543
568
544-- | /O(1)/ Returns all characters after the head of a 'Text', which
569-- | /O(1)/ Returns all characters after the head of a 'Text', which
545-- must be non-empty. Subject to fusion.
570-- must be non-empty. Subject to fusion.
@@ -551,12 +576,12 @@ tail = coerce JSS.tail
551-- where d = iter_ t 0
576-- where d = iter_ t 0
552{-# INLINE [1] tail #-}
577{-# INLINE [1] tail #-}
553
578
554−-- {-# RULES
579+{-# RULES
555−-- "TEXT tail -> fused" [~1] forall t.
580+"TEXT tail -> fused" [~1] forall t.
556−-- tail t = unstream (S.tail (stream t))
581+ tail t = unstream (S.tail (stream t))
557−-- "TEXT tail -> unfused" [1] forall t.
582+"TEXT tail -> unfused" [1] forall t.
558−-- unstream (S.tail (stream t)) = tail t
583+ unstream (S.tail (stream t)) = tail t
559−-- #-}
584+ #-}
560
585
561-- | /O(1)/ Returns all but the last character of a 'Text', which must
586-- | /O(1)/ Returns all but the last character of a 'Text', which must
562-- be non-empty. Subject to fusion.
587-- be non-empty. Subject to fusion.
@@ -569,12 +594,12 @@ init = coerce JSS.init
569-- n = A.unsafeIndex arr (off+len-1)
594-- n = A.unsafeIndex arr (off+len-1)
570{-# INLINE [1] init #-}
595{-# INLINE [1] init #-}
571
596
572−-- {-# RULES
597+{-# RULES
573−-- "TEXT init -> fused" [~1] forall t.
598+"TEXT init -> fused" [~1] forall t.
574−-- init t = unstream (S.init (stream t))
599+ init t = unstream (S.init (stream t))
575−-- "TEXT init -> unfused" [1] forall t.
600+"TEXT init -> unfused" [1] forall t.
576−-- unstream (S.init (stream t)) = init t
601+ unstream (S.init (stream t)) = init t
577−-- #-}
602+ #-}
578
603
579-- | /O(1)/ Tests whether a 'Text' is empty or not. Subject to
604-- | /O(1)/ Tests whether a 'Text' is empty or not. Subject to
580-- fusion.
605-- fusion.
@@ -587,12 +612,12 @@ null = coerce JSS.null
587-- len <= 0
612-- len <= 0
588{-# INLINE [1] null #-}
613{-# INLINE [1] null #-}
589
614
590−-- {-# RULES
615+{-# RULES
591−-- "TEXT null -> fused" [~1] forall t.
616+"TEXT null -> fused" [~1] forall t.
592−-- null t = S.null (stream t)
617+ null t = S.null (stream t)
593−-- "TEXT null -> unfused" [1] forall t.
618+"TEXT null -> unfused" [1] forall t.
594−-- S.null (stream t) = null t
619+ S.null (stream t) = null t
595−-- #-}
620+ #-}
596
621
597-- | /O(1)/ Tests whether a 'Text' contains exactly one character.
622-- | /O(1)/ Tests whether a 'Text' contains exactly one character.
598-- Subject to fusion.
623-- Subject to fusion.
@@ -616,44 +641,43 @@ length = coerce JSS.length
616-- of 'length', but can short circuit if the count of characters is
641-- of 'length', but can short circuit if the count of characters is
617-- greater than the number, and hence be more efficient.
642-- greater than the number, and hence be more efficient.
618compareLength :: Text -> Int -> Ordering
643compareLength :: Text -> Int -> Ordering
619−compareLength t n = compare (length t) n
620−-- compareLength t n = S.compareLengthI (stream t) n
644+compareLength t n = S.compareLengthI (stream t) n
621−-- {-# INLINE [1] compareLength #-}
645+{-# INLINE [1] compareLength #-}
622−--
646+
623−-- {-# RULES
647+{-# RULES
624−-- "TEXT compareN/length -> compareLength" [~1] forall t n.
648+"TEXT compareN/length -> compareLength" [~1] forall t n.
625−-- compare (length t) n = compareLength t n
649+ compare (length t) n = compareLength t n
626−-- #-}
650+ #-}
627−--
651+
628−-- {-# RULES
652+{-# RULES
629−-- "TEXT ==N/length -> compareLength/==EQ" [~1] forall t n.
653+"TEXT ==N/length -> compareLength/==EQ" [~1] forall t n.
630−-- eqInt (length t) n = compareLength t n == EQ
654+ eqInt (length t) n = compareLength t n == EQ
631−-- #-}
655+ #-}
632−--
656+
633−-- {-# RULES
657+{-# RULES
634−-- "TEXT /=N/length -> compareLength//=EQ" [~1] forall t n.
658+"TEXT /=N/length -> compareLength//=EQ" [~1] forall t n.
635−-- neInt (length t) n = compareLength t n /= EQ
659+ neInt (length t) n = compareLength t n /= EQ
636−-- #-}
660+ #-}
637−--
661+
638−-- {-# RULES
662+{-# RULES
639−-- "TEXT <N/length -> compareLength/==LT" [~1] forall t n.
663+"TEXT <N/length -> compareLength/==LT" [~1] forall t n.
640−-- ltInt (length t) n = compareLength t n == LT
664+ ltInt (length t) n = compareLength t n == LT
641−-- #-}
665+ #-}
642−--
666+
643−-- {-# RULES
667+{-# RULES
644−-- "TEXT <=N/length -> compareLength//=GT" [~1] forall t n.
668+"TEXT <=N/length -> compareLength//=GT" [~1] forall t n.
645−-- leInt (length t) n = compareLength t n /= GT
669+ leInt (length t) n = compareLength t n /= GT
646−-- #-}
670+ #-}
647−--
671+
648−-- {-# RULES
672+{-# RULES
649−-- "TEXT >N/length -> compareLength/==GT" [~1] forall t n.
673+"TEXT >N/length -> compareLength/==GT" [~1] forall t n.
650−-- gtInt (length t) n = compareLength t n == GT
674+ gtInt (length t) n = compareLength t n == GT
651−-- #-}
675+ #-}
652−--
676+
653−-- {-# RULES
677+{-# RULES
654−-- "TEXT >=N/length -> compareLength//=LT" [~1] forall t n.
678+"TEXT >=N/length -> compareLength//=LT" [~1] forall t n.
655−-- geInt (length t) n = compareLength t n /= LT
679+ geInt (length t) n = compareLength t n /= LT
656−-- #-}
680+ #-}
657
681
658-- -----------------------------------------------------------------------------
682-- -----------------------------------------------------------------------------
659-- * Transformations
683-- * Transformations
@@ -845,12 +869,12 @@ justifyLeft = coerce JSS.justifyLeft
845-- where len = length t
869-- where len = length t
846{-# INLINE [1] justifyLeft #-}
870{-# INLINE [1] justifyLeft #-}
847
871
848−-- {-# RULES
872+{-# RULES
849−-- "TEXT justifyLeft -> fused" [~1] forall k c t.
873+"TEXT justifyLeft -> fused" [~1] forall k c t.
850−-- justifyLeft k c t = unstream (S.justifyLeftI k c (stream t))
874+ justifyLeft k c t = unstream (S.justifyLeftI k c (stream t))
851−-- "TEXT justifyLeft -> unfused" [1] forall k c t.
875+"TEXT justifyLeft -> unfused" [1] forall k c t.
852−-- unstream (S.justifyLeftI k c (stream t)) = justifyLeft k c t
876+ unstream (S.justifyLeftI k c (stream t)) = justifyLeft k c t
853−-- #-}
877+ #-}
854
878
855-- | /O(n)/ Right-justify a string to the given length, using the
879-- | /O(n)/ Right-justify a string to the given length, using the
856-- specified fill character on the left. Performs replacement on
880-- specified fill character on the left. Performs replacement on
@@ -1094,16 +1118,27 @@ replicate = coerce JSS.replicate
1094-- loop 0 0
1118-- loop 0 0
1095{-# INLINE [1] replicate #-}
1119{-# INLINE [1] replicate #-}
1096
1120
1097−-- {-# RULES
1121+{-# RULES
1098−-- "TEXT replicate/singleton -> replicateChar" [~1] forall n c.
1122+"TEXT replicate/singleton -> replicateChar" [~1] forall n c.
1099−-- replicate n (singleton c) = replicateChar n c
1123+ replicate n (singleton c) = replicateChar n c
1100−-- #-}
1124+ #-}
1101
1125
1102-- | /O(n)/ 'replicateChar' @n@ @c@ is a 'Text' of length @n@ with @c@ the
1126-- | /O(n)/ 'replicateChar' @n@ @c@ is a 'Text' of length @n@ with @c@ the
1103-- value of every element. Subject to fusion.
1127-- value of every element. Subject to fusion.
1104−-- replicateChar :: Int -> Char -> Text
1128+replicateChar :: Int -> Char -> Text
1129+#ifndef __GHCJS__
1105−-- replicateChar n c = unstream (S.replicateCharI n (safe c))
1130+replicateChar n c = unstream (S.replicateCharI n (safe c))
1131+{-# INLINE replicateChar #-}
1132+#else
1133+replicateChar n c = Text $ js_replicateChar n c
1106−-- {-# INLINE replicateChar #-}
1134+{-# INLINE [1] replicateChar #-}
1135+{-# RULES
1136+"JSSTRING replicateChar -> fused" [~1] forall n c.
1137+ replicateChar n c = unstream (S.replicateCharI n (safe c))
1138+"JSSTRING replicateChar -> unfused" [1] forall n c.
1139+ unstream (S.replicateCharI n (safe c)) = replicateChar n c
1140+ #-}
1141+#endif
1107
1142
1108-- | /O(n)/, where @n@ is the length of the result. The 'unfoldr'
1143-- | /O(n)/, where @n@ is the length of the result. The 'unfoldr'
1109-- function is analogous to the List 'L.unfoldr'. 'unfoldr' builds a
1144-- function is analogous to the List 'L.unfoldr'. 'unfoldr' builds a
@@ -1149,12 +1184,12 @@ take = coerce JSS.take
1149-- | otherwise = loop (i+d) (cnt+1)
1184-- | otherwise = loop (i+d) (cnt+1)
1150-- where d = iter_ t i
1185-- where d = iter_ t i
1151
1186
1152−-- {-# RULES
1187+{-# RULES
1153−-- "TEXT take -> fused" [~1] forall n t.
1188+"TEXT take -> fused" [~1] forall n t.
1154−-- take n t = unstream (S.take n (stream t))
1189+ take n t = unstream (S.take n (stream t))
1155−-- "TEXT take -> unfused" [1] forall n t.
1190+"TEXT take -> unfused" [1] forall n t.
1156−-- unstream (S.take n (stream t)) = take n t
1191+ unstream (S.take n (stream t)) = take n t
1157−-- #-}
1192+ #-}
1158
1193
1159-- | /O(n)/ 'takeEnd' @n@ @t@ returns the suffix remaining after
1194-- | /O(n)/ 'takeEnd' @n@ @t@ returns the suffix remaining after
1160-- taking @n@ characters from the end of @t@.
1195-- taking @n@ characters from the end of @t@.
@@ -1190,12 +1225,12 @@ drop = coerce JSS.drop
1190-- where i = iterN n t
1225-- where i = iterN n t
1191{-# INLINE [1] drop #-}
1226{-# INLINE [1] drop #-}
1192
1227
1193−-- {-# RULES
1228+{-# RULES
1194−-- "TEXT drop -> fused" [~1] forall n t.
1229+"TEXT drop -> fused" [~1] forall n t.
1195−-- drop n t = unstream (S.drop n (stream t))
1230+ drop n t = unstream (S.drop n (stream t))
1196−-- "TEXT drop -> unfused" [1] forall n t.
1231+"TEXT drop -> unfused" [1] forall n t.
1197−-- unstream (S.drop n (stream t)) = drop n t
1232+ unstream (S.drop n (stream t)) = drop n t
1198−-- #-}
1233+ #-}
1199
1234
1200-- | /O(n)/ 'dropEnd' @n@ @t@ returns the prefix remaining after
1235-- | /O(n)/ 'dropEnd' @n@ @t@ returns the prefix remaining after
1201-- dropping @n@ characters from the end of @t@.
1236-- dropping @n@ characters from the end of @t@.
@@ -1222,12 +1257,12 @@ takeWhile = coerce JSS.takeWhile
1222-- where Iter c d = iter t i
1257-- where Iter c d = iter t i
1223{-# INLINE [1] takeWhile #-}
1258{-# INLINE [1] takeWhile #-}
1224
1259
1225−-- {-# RULES
1260+{-# RULES
1226−-- "TEXT takeWhile -> fused" [~1] forall p t.
1261+"TEXT takeWhile -> fused" [~1] forall p t.
1227−-- takeWhile p t = unstream (S.takeWhile p (stream t))
1262+ takeWhile p t = unstream (S.takeWhile p (stream t))
1228−-- "TEXT takeWhile -> unfused" [1] forall p t.
1263+"TEXT takeWhile -> unfused" [1] forall p t.
1229−-- unstream (S.takeWhile p (stream t)) = takeWhile p t
1264+ unstream (S.takeWhile p (stream t)) = takeWhile p t
1230−-- #-}
1265+ #-}
1231
1266
1232-- | /O(n)/ 'takeWhileEnd', applied to a predicate @p@ and a 'Text',
1267-- | /O(n)/ 'takeWhileEnd', applied to a predicate @p@ and a 'Text',
1233-- returns the longest suffix (possibly empty) of elements that
1268-- returns the longest suffix (possibly empty) of elements that
@@ -1236,7 +1271,7 @@ takeWhile = coerce JSS.takeWhile
1236--
1271--
1237-- > takeWhileEnd (=='o') "foo" == "oo"
1272-- > takeWhileEnd (=='o') "foo" == "oo"
1238takeWhileEnd :: (Char -> Bool) -> Text -> Text
1273takeWhileEnd :: (Char -> Bool) -> Text -> Text
1239−takeWhileEnd = P.undefined -- TODO
1274+takeWhileEnd = P.error "takeWhileEnd: not implemented."
1240-- takeWhileEnd :: (Char -> Bool) -> Text -> Text
1275-- takeWhileEnd :: (Char -> Bool) -> Text -> Text
1241-- takeWhileEnd p t@(Text arr off len) = loop (len-1) len
1276-- takeWhileEnd p t@(Text arr off len) = loop (len-1) len
1242-- where loop !i !l | l <= 0 = t
1277-- where loop !i !l | l <= 0 = t
@@ -1245,12 +1280,12 @@ takeWhileEnd = P.undefined -- TODO
1245-- where (c,d) = reverseIter t i
1280-- where (c,d) = reverseIter t i
1246{-# INLINE [1] takeWhileEnd #-}
1281{-# INLINE [1] takeWhileEnd #-}
1247
1282
1248−-- {-# RULES
1283+{-# RULES
1249−-- "TEXT takeWhileEnd -> fused" [~1] forall p t.
1284+"TEXT takeWhileEnd -> fused" [~1] forall p t.
1250−-- takeWhileEnd p t = S.reverse (S.takeWhile p (S.reverseStream t))
1285+ takeWhileEnd p t = S.reverse (S.takeWhile p (S.reverseStream t))
1251−-- "TEXT takeWhileEnd -> unfused" [1] forall p t.
1286+"TEXT takeWhileEnd -> unfused" [1] forall p t.
1252−-- S.reverse (S.takeWhile p (S.reverseStream t)) = takeWhileEnd p t
1287+ S.reverse (S.takeWhile p (S.reverseStream t)) = takeWhileEnd p t
1253−-- #-}
1288+ #-}
1254
1289
1255-- | /O(n)/ 'dropWhile' @p@ @t@ returns the suffix remaining after
1290-- | /O(n)/ 'dropWhile' @p@ @t@ returns the suffix remaining after
1256-- 'takeWhile' @p@ @t@. Subject to fusion.
1291-- 'takeWhile' @p@ @t@. Subject to fusion.
@@ -1263,12 +1298,12 @@ dropWhile = coerce JSS.dropWhile
1263
1298
1264{-# INLINE [1] dropWhile #-}
1299{-# INLINE [1] dropWhile #-}
1265
1300
1266−-- {-# RULES
1301+{-# RULES
1267−-- "TEXT dropWhile -> fused" [~1] forall p t.
1302+"TEXT dropWhile -> fused" [~1] forall p t.
1268−-- dropWhile p t = unstream (S.dropWhile p (stream t))
1303+ dropWhile p t = unstream (S.dropWhile p (stream t))
1269−-- "TEXT dropWhile -> unfused" [1] forall p t.
1304+"TEXT dropWhile -> unfused" [1] forall p t.
1270−-- unstream (S.dropWhile p (stream t)) = dropWhile p t
1305+ unstream (S.dropWhile p (stream t)) = dropWhile p t
1271−-- #-}
1306+ #-}
1272
1307
1273-- | /O(n)/ 'dropWhileEnd' @p@ @t@ returns the prefix remaining after
1308-- | /O(n)/ 'dropWhileEnd' @p@ @t@ returns the prefix remaining after
1274-- dropping characters that satisfy the predicate @p@ from the end of
1309-- dropping characters that satisfy the predicate @p@ from the end of
@@ -1286,12 +1321,12 @@ dropWhileEnd = coerce JSS.dropWhileEnd
1286-- where (c,d) = reverseIter t i
1321-- where (c,d) = reverseIter t i
1287{-# INLINE [1] dropWhileEnd #-}
1322{-# INLINE [1] dropWhileEnd #-}
1288
1323
1289−-- {-# RULES
1324+{-# RULES
1290−-- "TEXT dropWhileEnd -> fused" [~1] forall p t.
1325+"TEXT dropWhileEnd -> fused" [~1] forall p t.
1291−-- dropWhileEnd p t = S.reverse (S.dropWhile p (S.reverseStream t))
1326+ dropWhileEnd p t = S.reverse (S.dropWhile p (S.reverseStream t))
1292−-- "TEXT dropWhileEnd -> unfused" [1] forall p t.
1327+"TEXT dropWhileEnd -> unfused" [1] forall p t.
1293−-- S.reverse (S.dropWhile p (S.reverseStream t)) = dropWhileEnd p t
1328+ S.reverse (S.dropWhile p (S.reverseStream t)) = dropWhileEnd p t
1294−-- #-}
1329+ #-}
1295
1330
1296-- | /O(n)/ 'dropAround' @p@ @t@ returns the substring remaining after
1331-- | /O(n)/ 'dropAround' @p@ @t@ returns the substring remaining after
1297-- dropping characters that satisfy the predicate @p@ from both the
1332-- dropping characters that satisfy the predicate @p@ from both the
@@ -1430,10 +1465,10 @@ splitOn = coerce JSS.splitOn
1430-- go s _ = [text arr (s+off) (len-s)]
1465-- go s _ = [text arr (s+off) (len-s)]
1431{-# INLINE [1] splitOn #-}
1466{-# INLINE [1] splitOn #-}
1432
1467
1433−-- {-# RULES
1468+{-# RULES
1434−-- "TEXT splitOn/singleton -> split/==" [~1] forall c t.
1469+"TEXT splitOn/singleton -> split/==" [~1] forall c t.
1435−-- splitOn (singleton c) t = split (==c) t
1470+ splitOn (singleton c) t = split (==c) t
1436−-- #-}
1471+ #-}
1437
1472
1438-- | /O(n)/ Splits a 'Text' into components delimited by separators,
1473-- | /O(n)/ Splits a 'Text' into components delimited by separators,
1439-- where the predicate returns True for a separator element. The
1474-- where the predicate returns True for a separator element. The
@@ -1619,16 +1654,16 @@ count = coerce JSS.count
1619-- | otherwise = L.length (indices pat src)
1654-- | otherwise = L.length (indices pat src)
1620{-# INLINE [1] count #-}
1655{-# INLINE [1] count #-}
1621
1656
1622−-- {-# RULES
1657+{-# RULES
1623−-- "TEXT count/singleton -> countChar" [~1] forall c t.
1658+"TEXT count/singleton -> countChar" [~1] forall c t.
1624−-- count (singleton c) t = countChar c t
1659+ count (singleton c) t = countChar c t
1625−-- #-}
1660+ #-}
1626
1661
1627-- | /O(n)/ The 'countChar' function returns the number of times the
1662-- | /O(n)/ The 'countChar' function returns the number of times the
1628-- query element appears in the given 'Text'. Subject to fusion.
1663-- query element appears in the given 'Text'. Subject to fusion.
1629−-- countChar :: Char -> Text -> Int
1664+countChar :: Char -> Text -> Int
1630−-- countChar c t = S.countChar c (stream t)
1665+countChar c t = S.countChar c (stream t)
1631−-- {-# INLINE countChar #-}
1666+{-# INLINE countChar #-}
1632
1667
1633-------------------------------------------------------------------------------
1668-------------------------------------------------------------------------------
1634-- * Zipping
1669-- * Zipping
@@ -1723,10 +1758,12 @@ isPrefixOf = coerce JSS.isPrefixOf
1723-- alen <= blen && S.isPrefixOf (stream a) (stream b)
1758-- alen <= blen && S.isPrefixOf (stream a) (stream b)
1724{-# INLINE [1] isPrefixOf #-}
1759{-# INLINE [1] isPrefixOf #-}
1725
1760
1726−-- {-# RULES
1761+{-# RULES
1727−-- "TEXT isPrefixOf -> fused" [~1] forall s t.
1762+"TEXT isPrefixOf -> fused" [~1] forall s t.
1728−-- isPrefixOf s t = S.isPrefixOf (stream s) (stream t)
1763+ isPrefixOf s t = S.isPrefixOf (stream s) (stream t)
1764+"JSSTRING isPrefixOf -> unfused" [1] forall x y.
1765+ S.isPrefixOf (stream x) (stream y) = isPrefixOf x y
1729−-- #-}
1766+ #-}
1730
1767
1731-- | /O(n)/ The 'isSuffixOf' function takes two 'Text's and returns
1768-- | /O(n)/ The 'isSuffixOf' function takes two 'Text's and returns
1732-- 'True' iff the first is a suffix of the second.
1769-- 'True' iff the first is a suffix of the second.
@@ -1753,10 +1790,10 @@ isInfixOf = coerce JSS.isInfixOf
1753-- | otherwise = not . L.null . indices needle $ haystack
1790-- | otherwise = not . L.null . indices needle $ haystack
1754{-# INLINE [1] isInfixOf #-}
1791{-# INLINE [1] isInfixOf #-}
1755
1792
1756−-- {-# RULES
1793+{-# RULES
1757−-- "TEXT isInfixOf/singleton -> S.elem/S.stream" [~1] forall n h.
1794+"TEXT isInfixOf/singleton -> S.elem/S.stream" [~1] forall n h.
1758−-- isInfixOf (singleton n) h = S.elem n (S.stream h)
1795+ isInfixOf (singleton n) h = S.elem n (S.stream h)
1759−-- #-}
1796+ #-}
1760
1797
1761-------------------------------------------------------------------------------
1798-------------------------------------------------------------------------------
1762-- * View patterns
1799-- * View patterns
@@ -1864,3 +1901,5 @@ copy = P.id -- TODO
1864-- go = do
1901-- go = do
1865-- marr <- A.new len
1902-- marr <- A.new len
1866
1903
1904+foreign import javascript unsafe
1905+ "h$jsstringReplicateChar" js_replicateChar :: Int -> Char -> JSString
Data/Text/Internal/Fusion.hs+12
@@ -72,35 +72,47 @@ default(Int)
72
72
73stream :: Text -> Stream Char
73stream :: Text -> Stream Char
74stream = coerce JSS.stream
74stream = coerce JSS.stream
75+{-# INLINE [0] stream #-}
75
76
76reverseStream :: Text -> Stream Char
77reverseStream :: Text -> Stream Char
77reverseStream = coerce JSS.reverseStream
78reverseStream = coerce JSS.reverseStream
79+{-# INLINE [0] reverseStream #-}
78
80
79unstream :: Stream Char -> Text
81unstream :: Stream Char -> Text
80unstream = coerce JSS.unstream
82unstream = coerce JSS.unstream
83+{-# INLINE [0] unstream #-}
84+{-# RULES "STREAM stream/unstream fusion" forall s. stream (unstream s) = s #-}
81
85
82length :: Stream Char -> Int
86length :: Stream Char -> Int
83length = JSS.length
87length = JSS.length
88+{-# INLINE [0] length #-}
84
89
85reverse :: Stream Char -> Text
90reverse :: Stream Char -> Text
86reverse = coerce JSS.reverse
91reverse = coerce JSS.reverse
92+{-# INLINE [0] reverse #-}
87
93
88reverseScanr :: (Char -> Char -> Char) -> Char -> Stream Char -> Stream Char
94reverseScanr :: (Char -> Char -> Char) -> Char -> Stream Char -> Stream Char
89reverseScanr = JSS.reverseScanr
95reverseScanr = JSS.reverseScanr
96+{-# INLINE reverseScanr #-}
90
97
91mapAccumL :: (a -> Char -> (a, Char)) -> a -> Stream Char -> (a, Text)
98mapAccumL :: (a -> Char -> (a, Char)) -> a -> Stream Char -> (a, Text)
92mapAccumL f z0 st =
99mapAccumL f z0 st =
93 let (a, t) = JSS.mapAccumL f z0 st
100 let (a, t) = JSS.mapAccumL f z0 st
94 in (a, Text t)
101 in (a, Text t)
102+{-# INLINE [0] mapAccumL #-}
95
103
96unfoldrN :: Int -> (a -> Maybe (Char,a)) -> a -> Stream Char
104unfoldrN :: Int -> (a -> Maybe (Char,a)) -> a -> Stream Char
97unfoldrN = JSS.unfoldrN
105unfoldrN = JSS.unfoldrN
106+{-# INLINE [0] unfoldrN #-}
98
107
99index :: Stream Char -> Int -> Char
108index :: Stream Char -> Int -> Char
100index = JSS.index
109index = JSS.index
110+{-# INLINE [0] index #-}
101
111
102findIndex :: (Char -> Bool) -> Stream Char -> Maybe Int
112findIndex :: (Char -> Bool) -> Stream Char -> Maybe Int
103findIndex = JSS.findIndex
113findIndex = JSS.findIndex
114+{-# INLINE [0] findIndex #-}
104
115
105countChar :: Char -> Stream Char -> Int
116countChar :: Char -> Stream Char -> Int
106countChar = JSS.countChar
117countChar = JSS.countChar
118+{-# INLINE [0] countChar #-}