on master help sign in
rules and inlines
commit4e9f934e9defbc6050c2de4b22487b77a6db45a8 authorLuigy Leon <luigy@outlook.com> dateTue 4 Oct 2016, 18:09 (10 years ago) parentc79eced
2 files changed+189−138
Data/Text.hs+177−138 Data/Text/Internal/Fusion.hs+12
Data/Text.hs+177−138
@@ -224,7 +224,7 @@ import qualified Data.Text.Internal.Fusion.Common as S
224224import Data.Text.Encoding (decodeUtf8', encodeUtf8)
225225import Data.Text.Internal.Fusion (stream, reverseStream, unstream)
226226-- 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)
228228-- import Data.Text.Show (singleton, unpack, unpackCString#)
229229import qualified Prelude as P
230230import Data.Text.Unsafe (Iter(..), iter, iter_, lengthWord16, reverseIter,
@@ -253,19 +253,44 @@ import qualified Data.JSString.Internal.Fusion as SJS
253253import qualified Data.JSString.Internal.Fusion.Common as SJS
254254import Data.Coerce
255255import GHC.Exts (Addr#)
256+import qualified GHC.CString as GHC
256257
257258unpack :: Text -> String
258259unpack = coerce JSS.unpack
260+{-# INLINE [1] unpack #-}
259261
260262singleton :: Char -> Text
261263singleton = coerce JSS.singleton
262264{-# INLINE [1] singleton #-}
263265
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+ #-}
264272
265273-- | /O(n)/ Convert a literal string into a JSString. Subject to fusion.
266274unpackCString# :: Addr# -> Text
267275unpackCString# addr# = Text $ SJS.unstream (SJS.streamCString# addr#)
268276{-# 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+
269294---------------------------------------------------------------------
270295
271296-- $strict
@@ -494,12 +519,12 @@ append = coerce JSS.append
494519-- return arr
495520{-# NOINLINE append #-}
496521
497−-- {-# RULES
498−-- "TEXT append -> fused" [~1] forall t1 t2.
499−-- append t1 t2 = unstream (S.append (stream t1) (stream t2))
500−-- "TEXT append -> unfused" [1] forall t1 t2.
501−-- unstream (S.append (stream t1) (stream t2)) = append t1 t2
502−-- #-}
522+{-# RULES
523+"TEXT append -> fused" [~1] forall t1 t2.
524+ append t1 t2 = unstream (S.append (stream t1) (stream t2))
525+"TEXT append -> unfused" [1] forall t1 t2.
526+ unstream (S.append (stream t1) (stream t2)) = append t1 t2
527+ #-}
503528
504529-- | /O(1)/ Returns the first character of a 'Text', which must be
505530-- non-empty. Subject to fusion.
@@ -534,12 +559,12 @@ last = coerce JSS.last
534559-- n0 = A.unsafeIndex arr (off+len-2)
535560{-# INLINE [1] last #-}
536561
537−-- {-# RULES
538−-- "TEXT last -> fused" [~1] forall t.
539−-- last t = S.last (stream t)
540−-- "TEXT last -> unfused" [1] forall t.
541−-- S.last (stream t) = last t
542−-- #-}
562+{-# RULES
563+"TEXT last -> fused" [~1] forall t.
564+ last t = S.last (stream t)
565+"TEXT last -> unfused" [1] forall t.
566+ S.last (stream t) = last t
567+ #-}
543568
544569-- | /O(1)/ Returns all characters after the head of a 'Text', which
545570-- must be non-empty. Subject to fusion.
@@ -551,12 +576,12 @@ tail = coerce JSS.tail
551576-- where d = iter_ t 0
552577{-# INLINE [1] tail #-}
553578
554−-- {-# RULES
555−-- "TEXT tail -> fused" [~1] forall t.
556−-- tail t = unstream (S.tail (stream t))
557−-- "TEXT tail -> unfused" [1] forall t.
558−-- unstream (S.tail (stream t)) = tail t
559−-- #-}
579+{-# RULES
580+"TEXT tail -> fused" [~1] forall t.
581+ tail t = unstream (S.tail (stream t))
582+"TEXT tail -> unfused" [1] forall t.
583+ unstream (S.tail (stream t)) = tail t
584+ #-}
560585
561586-- | /O(1)/ Returns all but the last character of a 'Text', which must
562587-- be non-empty. Subject to fusion.
@@ -569,12 +594,12 @@ init = coerce JSS.init
569594-- n = A.unsafeIndex arr (off+len-1)
570595{-# INLINE [1] init #-}
571596
572−-- {-# RULES
573−-- "TEXT init -> fused" [~1] forall t.
574−-- init t = unstream (S.init (stream t))
575−-- "TEXT init -> unfused" [1] forall t.
576−-- unstream (S.init (stream t)) = init t
577−-- #-}
597+{-# RULES
598+"TEXT init -> fused" [~1] forall t.
599+ init t = unstream (S.init (stream t))
600+"TEXT init -> unfused" [1] forall t.
601+ unstream (S.init (stream t)) = init t
602+ #-}
578603
579604-- | /O(1)/ Tests whether a 'Text' is empty or not. Subject to
580605-- fusion.
@@ -587,12 +612,12 @@ null = coerce JSS.null
587612-- len <= 0
588613{-# INLINE [1] null #-}
589614
590−-- {-# RULES
591−-- "TEXT null -> fused" [~1] forall t.
592−-- null t = S.null (stream t)
593−-- "TEXT null -> unfused" [1] forall t.
594−-- S.null (stream t) = null t
595−-- #-}
615+{-# RULES
616+"TEXT null -> fused" [~1] forall t.
617+ null t = S.null (stream t)
618+"TEXT null -> unfused" [1] forall t.
619+ S.null (stream t) = null t
620+ #-}
596621
597622-- | /O(1)/ Tests whether a 'Text' contains exactly one character.
598623-- Subject to fusion.
@@ -616,44 +641,43 @@ length = coerce JSS.length
616641-- of 'length', but can short circuit if the count of characters is
617642-- greater than the number, and hence be more efficient.
618643compareLength :: Text -> Int -> Ordering
619−compareLength t n = compare (length t) n
620−-- compareLength t n = S.compareLengthI (stream t) n
621−-- {-# INLINE [1] compareLength #-}
622−--
623−-- {-# RULES
624−-- "TEXT compareN/length -> compareLength" [~1] forall t n.
625−-- compare (length t) n = compareLength t n
626−-- #-}
627−--
628−-- {-# RULES
629−-- "TEXT ==N/length -> compareLength/==EQ" [~1] forall t n.
630−-- eqInt (length t) n = compareLength t n == EQ
631−-- #-}
632−--
633−-- {-# RULES
634−-- "TEXT /=N/length -> compareLength//=EQ" [~1] forall t n.
635−-- neInt (length t) n = compareLength t n /= EQ
636−-- #-}
637−--
638−-- {-# RULES
639−-- "TEXT <N/length -> compareLength/==LT" [~1] forall t n.
640−-- ltInt (length t) n = compareLength t n == LT
641−-- #-}
642−--
643−-- {-# RULES
644−-- "TEXT <=N/length -> compareLength//=GT" [~1] forall t n.
645−-- leInt (length t) n = compareLength t n /= GT
646−-- #-}
647−--
648−-- {-# RULES
649−-- "TEXT >N/length -> compareLength/==GT" [~1] forall t n.
650−-- gtInt (length t) n = compareLength t n == GT
651−-- #-}
652−--
653−-- {-# RULES
654−-- "TEXT >=N/length -> compareLength//=LT" [~1] forall t n.
655−-- geInt (length t) n = compareLength t n /= LT
656−-- #-}
644+compareLength t n = S.compareLengthI (stream t) n
645+{-# INLINE [1] compareLength #-}
646+
647+{-# RULES
648+"TEXT compareN/length -> compareLength" [~1] forall t n.
649+ compare (length t) n = compareLength t n
650+ #-}
651+
652+{-# RULES
653+"TEXT ==N/length -> compareLength/==EQ" [~1] forall t n.
654+ eqInt (length t) n = compareLength t n == EQ
655+ #-}
656+
657+{-# RULES
658+"TEXT /=N/length -> compareLength//=EQ" [~1] forall t n.
659+ neInt (length t) n = compareLength t n /= EQ
660+ #-}
661+
662+{-# RULES
663+"TEXT <N/length -> compareLength/==LT" [~1] forall t n.
664+ ltInt (length t) n = compareLength t n == LT
665+ #-}
666+
667+{-# RULES
668+"TEXT <=N/length -> compareLength//=GT" [~1] forall t n.
669+ leInt (length t) n = compareLength t n /= GT
670+ #-}
671+
672+{-# RULES
673+"TEXT >N/length -> compareLength/==GT" [~1] forall t n.
674+ gtInt (length t) n = compareLength t n == GT
675+ #-}
676+
677+{-# RULES
678+"TEXT >=N/length -> compareLength//=LT" [~1] forall t n.
679+ geInt (length t) n = compareLength t n /= LT
680+ #-}
657681
658682-- -----------------------------------------------------------------------------
659683-- * Transformations
@@ -845,12 +869,12 @@ justifyLeft = coerce JSS.justifyLeft
845869-- where len = length t
846870{-# INLINE [1] justifyLeft #-}
847871
848−-- {-# RULES
849−-- "TEXT justifyLeft -> fused" [~1] forall k c t.
850−-- justifyLeft k c t = unstream (S.justifyLeftI k c (stream t))
851−-- "TEXT justifyLeft -> unfused" [1] forall k c t.
852−-- unstream (S.justifyLeftI k c (stream t)) = justifyLeft k c t
853−-- #-}
872+{-# RULES
873+"TEXT justifyLeft -> fused" [~1] forall k c t.
874+ justifyLeft k c t = unstream (S.justifyLeftI k c (stream t))
875+"TEXT justifyLeft -> unfused" [1] forall k c t.
876+ unstream (S.justifyLeftI k c (stream t)) = justifyLeft k c t
877+ #-}
854878
855879-- | /O(n)/ Right-justify a string to the given length, using the
856880-- specified fill character on the left. Performs replacement on
@@ -1094,16 +1118,27 @@ replicate = coerce JSS.replicate
10941118-- loop 0 0
10951119{-# INLINE [1] replicate #-}
10961120
1097−-- {-# RULES
1098−-- "TEXT replicate/singleton -> replicateChar" [~1] forall n c.
1099−-- replicate n (singleton c) = replicateChar n c
1100−-- #-}
1121+{-# RULES
1122+"TEXT replicate/singleton -> replicateChar" [~1] forall n c.
1123+ replicate n (singleton c) = replicateChar n c
1124+ #-}
11011125
11021126-- | /O(n)/ 'replicateChar' @n@ @c@ is a 'Text' of length @n@ with @c@ the
11031127-- value of every element. Subject to fusion.
1104−-- replicateChar :: Int -> Char -> Text
1105−-- replicateChar n c = unstream (S.replicateCharI n (safe c))
1106−-- {-# INLINE replicateChar #-}
1128+replicateChar :: Int -> Char -> Text
1129+#ifndef __GHCJS__
1130+replicateChar n c = unstream (S.replicateCharI n (safe c))
1131+{-# INLINE replicateChar #-}
1132+#else
1133+replicateChar n c = Text $ js_replicateChar n c
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
11071142
11081143-- | /O(n)/, where @n@ is the length of the result. The 'unfoldr'
11091144-- function is analogous to the List 'L.unfoldr'. 'unfoldr' builds a
@@ -1149,12 +1184,12 @@ take = coerce JSS.take
11491184-- | otherwise = loop (i+d) (cnt+1)
11501185-- where d = iter_ t i
11511186
1152−-- {-# RULES
1153−-- "TEXT take -> fused" [~1] forall n t.
1154−-- take n t = unstream (S.take n (stream t))
1155−-- "TEXT take -> unfused" [1] forall n t.
1156−-- unstream (S.take n (stream t)) = take n t
1157−-- #-}
1187+{-# RULES
1188+"TEXT take -> fused" [~1] forall n t.
1189+ take n t = unstream (S.take n (stream t))
1190+"TEXT take -> unfused" [1] forall n t.
1191+ unstream (S.take n (stream t)) = take n t
1192+ #-}
11581193
11591194-- | /O(n)/ 'takeEnd' @n@ @t@ returns the suffix remaining after
11601195-- taking @n@ characters from the end of @t@.
@@ -1190,12 +1225,12 @@ drop = coerce JSS.drop
11901225-- where i = iterN n t
11911226{-# INLINE [1] drop #-}
11921227
1193−-- {-# RULES
1194−-- "TEXT drop -> fused" [~1] forall n t.
1195−-- drop n t = unstream (S.drop n (stream t))
1196−-- "TEXT drop -> unfused" [1] forall n t.
1197−-- unstream (S.drop n (stream t)) = drop n t
1198−-- #-}
1228+{-# RULES
1229+"TEXT drop -> fused" [~1] forall n t.
1230+ drop n t = unstream (S.drop n (stream t))
1231+"TEXT drop -> unfused" [1] forall n t.
1232+ unstream (S.drop n (stream t)) = drop n t
1233+ #-}
11991234
12001235-- | /O(n)/ 'dropEnd' @n@ @t@ returns the prefix remaining after
12011236-- dropping @n@ characters from the end of @t@.
@@ -1222,12 +1257,12 @@ takeWhile = coerce JSS.takeWhile
12221257-- where Iter c d = iter t i
12231258{-# INLINE [1] takeWhile #-}
12241259
1225−-- {-# RULES
1226−-- "TEXT takeWhile -> fused" [~1] forall p t.
1227−-- takeWhile p t = unstream (S.takeWhile p (stream t))
1228−-- "TEXT takeWhile -> unfused" [1] forall p t.
1229−-- unstream (S.takeWhile p (stream t)) = takeWhile p t
1230−-- #-}
1260+{-# RULES
1261+"TEXT takeWhile -> fused" [~1] forall p t.
1262+ takeWhile p t = unstream (S.takeWhile p (stream t))
1263+"TEXT takeWhile -> unfused" [1] forall p t.
1264+ unstream (S.takeWhile p (stream t)) = takeWhile p t
1265+ #-}
12311266
12321267-- | /O(n)/ 'takeWhileEnd', applied to a predicate @p@ and a 'Text',
12331268-- returns the longest suffix (possibly empty) of elements that
@@ -1236,7 +1271,7 @@ takeWhile = coerce JSS.takeWhile
12361271--
12371272-- > takeWhileEnd (=='o') "foo" == "oo"
12381273takeWhileEnd :: (Char -> Bool) -> Text -> Text
1239−takeWhileEnd = P.undefined -- TODO
1274+takeWhileEnd = P.error "takeWhileEnd: not implemented."
12401275-- takeWhileEnd :: (Char -> Bool) -> Text -> Text
12411276-- takeWhileEnd p t@(Text arr off len) = loop (len-1) len
12421277-- where loop !i !l | l <= 0 = t
@@ -1245,12 +1280,12 @@ takeWhileEnd = P.undefined -- TODO
12451280-- where (c,d) = reverseIter t i
12461281{-# INLINE [1] takeWhileEnd #-}
12471282
1248−-- {-# RULES
1249−-- "TEXT takeWhileEnd -> fused" [~1] forall p t.
1250−-- takeWhileEnd p t = S.reverse (S.takeWhile p (S.reverseStream t))
1251−-- "TEXT takeWhileEnd -> unfused" [1] forall p t.
1252−-- S.reverse (S.takeWhile p (S.reverseStream t)) = takeWhileEnd p t
1253−-- #-}
1283+{-# RULES
1284+"TEXT takeWhileEnd -> fused" [~1] forall p t.
1285+ takeWhileEnd p t = S.reverse (S.takeWhile p (S.reverseStream t))
1286+"TEXT takeWhileEnd -> unfused" [1] forall p t.
1287+ S.reverse (S.takeWhile p (S.reverseStream t)) = takeWhileEnd p t
1288+ #-}
12541289
12551290-- | /O(n)/ 'dropWhile' @p@ @t@ returns the suffix remaining after
12561291-- 'takeWhile' @p@ @t@. Subject to fusion.
@@ -1263,12 +1298,12 @@ dropWhile = coerce JSS.dropWhile
12631298
12641299{-# INLINE [1] dropWhile #-}
12651300
1266−-- {-# RULES
1267−-- "TEXT dropWhile -> fused" [~1] forall p t.
1268−-- dropWhile p t = unstream (S.dropWhile p (stream t))
1269−-- "TEXT dropWhile -> unfused" [1] forall p t.
1270−-- unstream (S.dropWhile p (stream t)) = dropWhile p t
1271−-- #-}
1301+{-# RULES
1302+"TEXT dropWhile -> fused" [~1] forall p t.
1303+ dropWhile p t = unstream (S.dropWhile p (stream t))
1304+"TEXT dropWhile -> unfused" [1] forall p t.
1305+ unstream (S.dropWhile p (stream t)) = dropWhile p t
1306+ #-}
12721307
12731308-- | /O(n)/ 'dropWhileEnd' @p@ @t@ returns the prefix remaining after
12741309-- dropping characters that satisfy the predicate @p@ from the end of
@@ -1286,12 +1321,12 @@ dropWhileEnd = coerce JSS.dropWhileEnd
12861321-- where (c,d) = reverseIter t i
12871322{-# INLINE [1] dropWhileEnd #-}
12881323
1289−-- {-# RULES
1290−-- "TEXT dropWhileEnd -> fused" [~1] forall p t.
1291−-- dropWhileEnd p t = S.reverse (S.dropWhile p (S.reverseStream t))
1292−-- "TEXT dropWhileEnd -> unfused" [1] forall p t.
1293−-- S.reverse (S.dropWhile p (S.reverseStream t)) = dropWhileEnd p t
1294−-- #-}
1324+{-# RULES
1325+"TEXT dropWhileEnd -> fused" [~1] forall p t.
1326+ dropWhileEnd p t = S.reverse (S.dropWhile p (S.reverseStream t))
1327+"TEXT dropWhileEnd -> unfused" [1] forall p t.
1328+ S.reverse (S.dropWhile p (S.reverseStream t)) = dropWhileEnd p t
1329+ #-}
12951330
12961331-- | /O(n)/ 'dropAround' @p@ @t@ returns the substring remaining after
12971332-- dropping characters that satisfy the predicate @p@ from both the
@@ -1430,10 +1465,10 @@ splitOn = coerce JSS.splitOn
14301465-- go s _ = [text arr (s+off) (len-s)]
14311466{-# INLINE [1] splitOn #-}
14321467
1433−-- {-# RULES
1434−-- "TEXT splitOn/singleton -> split/==" [~1] forall c t.
1435−-- splitOn (singleton c) t = split (==c) t
1436−-- #-}
1468+{-# RULES
1469+"TEXT splitOn/singleton -> split/==" [~1] forall c t.
1470+ splitOn (singleton c) t = split (==c) t
1471+ #-}
14371472
14381473-- | /O(n)/ Splits a 'Text' into components delimited by separators,
14391474-- where the predicate returns True for a separator element. The
@@ -1619,16 +1654,16 @@ count = coerce JSS.count
16191654-- | otherwise = L.length (indices pat src)
16201655{-# INLINE [1] count #-}
16211656
1622−-- {-# RULES
1623−-- "TEXT count/singleton -> countChar" [~1] forall c t.
1624−-- count (singleton c) t = countChar c t
1625−-- #-}
1657+{-# RULES
1658+"TEXT count/singleton -> countChar" [~1] forall c t.
1659+ count (singleton c) t = countChar c t
1660+ #-}
16261661
16271662-- | /O(n)/ The 'countChar' function returns the number of times the
16281663-- query element appears in the given 'Text'. Subject to fusion.
1629−-- countChar :: Char -> Text -> Int
1630−-- countChar c t = S.countChar c (stream t)
1631−-- {-# INLINE countChar #-}
1664+countChar :: Char -> Text -> Int
1665+countChar c t = S.countChar c (stream t)
1666+{-# INLINE countChar #-}
16321667
16331668-------------------------------------------------------------------------------
16341669-- * Zipping
@@ -1723,10 +1758,12 @@ isPrefixOf = coerce JSS.isPrefixOf
17231758-- alen <= blen && S.isPrefixOf (stream a) (stream b)
17241759{-# INLINE [1] isPrefixOf #-}
17251760
1726−-- {-# RULES
1727−-- "TEXT isPrefixOf -> fused" [~1] forall s t.
1728−-- isPrefixOf s t = S.isPrefixOf (stream s) (stream t)
1729−-- #-}
1761+{-# RULES
1762+"TEXT isPrefixOf -> fused" [~1] forall s 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
1766+ #-}
17301767
17311768-- | /O(n)/ The 'isSuffixOf' function takes two 'Text's and returns
17321769-- 'True' iff the first is a suffix of the second.
@@ -1753,10 +1790,10 @@ isInfixOf = coerce JSS.isInfixOf
17531790-- | otherwise = not . L.null . indices needle $ haystack
17541791{-# INLINE [1] isInfixOf #-}
17551792
1756−-- {-# RULES
1757−-- "TEXT isInfixOf/singleton -> S.elem/S.stream" [~1] forall n h.
1758−-- isInfixOf (singleton n) h = S.elem n (S.stream h)
1759−-- #-}
1793+{-# RULES
1794+"TEXT isInfixOf/singleton -> S.elem/S.stream" [~1] forall n h.
1795+ isInfixOf (singleton n) h = S.elem n (S.stream h)
1796+ #-}
17601797
17611798-------------------------------------------------------------------------------
17621799-- * View patterns
@@ -1864,3 +1901,5 @@ copy = P.id -- TODO
18641901-- go = do
18651902-- marr <- A.new len
18661903
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)
7272
7373stream :: Text -> Stream Char
7474stream = coerce JSS.stream
75+{-# INLINE [0] stream #-}
7576
7677reverseStream :: Text -> Stream Char
7778reverseStream = coerce JSS.reverseStream
79+{-# INLINE [0] reverseStream #-}
7880
7981unstream :: Stream Char -> Text
8082unstream = coerce JSS.unstream
83+{-# INLINE [0] unstream #-}
84+{-# RULES "STREAM stream/unstream fusion" forall s. stream (unstream s) = s #-}
8185
8286length :: Stream Char -> Int
8387length = JSS.length
88+{-# INLINE [0] length #-}
8489
8590reverse :: Stream Char -> Text
8691reverse = coerce JSS.reverse
92+{-# INLINE [0] reverse #-}
8793
8894reverseScanr :: (Char -> Char -> Char) -> Char -> Stream Char -> Stream Char
8995reverseScanr = JSS.reverseScanr
96+{-# INLINE reverseScanr #-}
9097
9198mapAccumL :: (a -> Char -> (a, Char)) -> a -> Stream Char -> (a, Text)
9299mapAccumL f z0 st =
93100 let (a, t) = JSS.mapAccumL f z0 st
94101 in (a, Text t)
102+{-# INLINE [0] mapAccumL #-}
95103
96104unfoldrN :: Int -> (a -> Maybe (Char,a)) -> a -> Stream Char
97105unfoldrN = JSS.unfoldrN
106+{-# INLINE [0] unfoldrN #-}
98107
99108index :: Stream Char -> Int -> Char
100109index = JSS.index
110+{-# INLINE [0] index #-}
101111
102112findIndex :: (Char -> Bool) -> Stream Char -> Maybe Int
103113findIndex = JSS.findIndex
114+{-# INLINE [0] findIndex #-}
104115
105116countChar :: Char -> Stream Char -> Int
106117countChar = JSS.countChar
118+{-# INLINE [0] countChar #-}