@@ -1,1404 +0,0 @@
1−{-# LANGUAGE MagicHash, BangPatterns, UnboxedTuples, TypeFamilies
2− #-}
3−{-# OPTIONS_GHC -fno-warn-orphans #-}
4−{-| Manipulation of JavaScript strings, API and fusion implementation
5− based on Data.Text by Tom Harper, Duncan Coutts, Bryan O'Sullivan e.a.
6− -}
7−module Data.JSString ( JSString
8−
9− -- * Creation and elimination
10− , pack
11− , unpack, unpack'
12− , singleton
13− , empty
14−
15− -- * Basic interface
16− , cons
17− , snoc
18− , append
19− , uncons
20− , head
21− , last
22− , tail
23− , init
24− , null
25− , length
26− , compareLength
27−
28− -- * Transformations
29− , map
30− , intercalate
31− , intersperse
32− , transpose
33− , reverse
34− , replace
35−
36− -- ** Case conversion
37− , toCaseFold
38− , toLower
39− , toUpper
40− , toTitle
41−
42− -- ** Justification
43− , justifyLeft
44− , justifyRight
45− , center
46−
47− -- * Folds
48− , foldl
49− , foldl'
50− , foldl1
51− , foldl1'
52− , foldr
53− , foldr1
54−
55− -- ** Special folds
56− , concat
57− , concatMap
58− , any
59− , all
60− , maximum
61− , minimum
62−
63− -- * Construction
64−
65− -- ** Scans
66− , scanl
67− , scanl1
68− , scanr
69− , scanr1
70−
71− -- ** Accumulating maps
72− , mapAccumL
73− , mapAccumR
74−
75− -- ** Generation and unfolding
76− , replicate
77− , unfoldr
78− , unfoldrN
79−
80− -- * Substrings
81−
82− -- ** Breaking strings
83− , take
84− , takeEnd
85− , drop
86− , dropEnd
87− , takeWhile
88− , dropWhile
89− , dropWhileEnd
90− , dropAround
91− , strip
92− , stripStart
93− , stripEnd
94− , splitAt
95− , breakOn
96− , breakOnEnd
97− , break
98− , span
99− , group
100− , group'
101− , groupBy
102− , inits
103− , tails
104−
105− -- ** Breaking into many substrings
106− , splitOn, splitOn'
107− , split
108− , chunksOf, chunksOf'
109−
110− -- ** Breaking into lines and words
111− , lines, lines'
112− , words, words'
113− , unlines
114− , unwords
115−
116− -- * Predicates
117− , isPrefixOf
118− , isSuffixOf
119− , isInfixOf
120−
121− -- ** View patterns
122− , stripPrefix
123− , stripSuffix
124− , commonPrefixes
125−
126− -- * Searching
127− , filter
128− , breakOnAll, breakOnAll'
129− , find
130− , partition
131−
132− -- * Indexing
133− , index
134− , findIndex
135− , count
136−
137− -- * Zipping
138− , zip
139− , zipWith
140− ) where
141−
142−import Prelude
143− ( Char, Bool(..), Int, Maybe(..), String, Eq(..), Ord(..), Ordering(..), (++)
144− , Read(..), Show(..), (&&), (||), (+), (-), (.), ($), ($!), (>>)
145− , not, seq, return, otherwise, quot)
146−import qualified Prelude as P
147−
148−import Control.DeepSeq (NFData(..))
149−import Data.Char (isSpace)
150−import Data.Coerce (coerce)
151−import qualified Data.List as L
152−import Data.Data
153−import qualified Data.Text as T
154−import qualified Data.Text.Internal.Fusion as TF
155−import qualified Data.Text.Internal.Fusion.Common as TF
156−
157−import GHC.Exts
158− ( Int#, (+#), (-#), (>=#), (>#), isTrue#, chr#, Char(..)
159− , Int(..), Addr#, tagToEnum#)
160−import qualified GHC.Exts as Exts
161−import qualified GHC.CString as GHC
162−
163−import Unsafe.Coerce
164−
165−import GHCJS.Prim (JSVal)
166−
167−import Data.JSString.Internal.Type
168−import Data.JSString.Internal.Fusion (stream, unstream)
169−import qualified Data.JSString.Internal.Fusion as S
170−import qualified Data.JSString.Internal.Fusion.Common as S
171−
172−instance Exts.IsList JSString where
173− type Item JSString = Char
174− fromList = pack
175− toList = unpack
176−
177−-- -----------------------------------------------------------------------------
178−-- * Conversion to/from 'JSString'
179−
180−-- | /O(n)/ Convert a 'String' into a 'JSString'. Subject to
181−-- fusion.
182−pack :: String -> JSString
183−pack = coerce T.pack
184−{-# INLINE [1] pack #-}
185−
186−{-# RULES
187−"JSSTRING pack -> fused" [~1] forall x.
188− pack x = unstream (S.map safe (S.streamList x))
189−"JSSTRING pack -> unfused" [1] forall x.
190− unstream (S.map safe (S.streamList x)) = pack x
191− #-}
192−
193−-- | /O(n)/ Convert a 'JSString' into a 'String'. Subject to fusion.
194−unpack :: JSString -> String
195−unpack = S.unstreamList . stream
196−{-# INLINE [1] unpack #-}
197−
198−unpack' :: JSString -> String
199−unpack' = coerce T.unpack
200−{-# INLINE unpack' #-}
201−
202−-- | /O(n)/ Convert a literal string into a JSString. Subject to fusion.
203−unpackCString# :: Addr# -> JSString
204−unpackCString# = coerce T.unpackCString#
205−{-# NOINLINE unpackCString# #-}
206−
207−{-# RULES "JSSTRING literal" forall a.
208− unstream (S.map safe (S.streamList (GHC.unpackCString# a)))
209− = unpackCString# a #-}
210−
211−{-# RULES "JSSTRING literal UTF8" forall a.
212− unstream (S.map safe (S.streamList (GHC.unpackCStringUtf8# a)))
213− = unpackCString# a #-}
214−
215−{-# RULES "JSSTRING empty literal"
216− unstream (S.map safe (S.streamList []))
217− = empty_ #-}
218−
219−{-# RULES "JSSTRING singleton literal" forall a.
220− unstream (S.map safe (S.streamList [a]))
221− = singleton a #-}
222−
223−
224−-- | /O(1)/ Convert a character into a 'JSString'. Subject to fusion.
225−-- Performs replacement on invalid scalar values.
226−singleton :: Char -> JSString
227−singleton = coerce T.singleton
228−{-# INLINE [1] singleton #-}
229−
230−{-# RULES
231−"JSSTRING singleton -> fused" [~1] forall a.
232− singleton a = unstream (S.singleton (safe a))
233−"JSSTRING singleton -> unfused" [1] forall a.
234− unstream (S.singleton (safe a)) = singleton a
235− #-}
236−
237−-- This is intended to reduce inlining bloat.
238−-- singleton_ :: Char -> Text
239−-- singleton_ c = js_singleton c
240−
241−-- Text (A.run x) 0 len
242−-- where x :: ST s (A.MArray s)
243−-- x = do arr <- A.new len
244−-- _ <- unsafeWrite arr 0 d
245−-- return arr
246−-- len | d < '\x10000' = 1
247−-- x | otherwise = 2
248−-- d = safe c
249−-- {-# NOINLINE singleton_ #-}
250−
251−-- -----------------------------------------------------------------------------
252−-- * Basic functions
253−
254−-- | /O(n)/ Adds a character to the front of a 'JSString'. This function
255−-- is more costly than its 'List' counterpart because it requires
256−-- copying a new array. Subject to fusion. Performs replacement on
257−-- invalid scalar values.
258−cons :: Char -> JSString -> JSString
259−cons = coerce T.cons
260−{-# INLINE [1] cons #-}
261−
262−{-# RULES
263−"JSSTRING cons -> fused" [~1] forall c x.
264− cons c x = unstream (S.cons (safe c) (stream x))
265−"JSSTRING cons -> unfused" [1] forall c x.
266− unstream (S.cons (safe c) (stream x)) = cons c x
267− #-}
268−
269−infixr 5 `cons`
270−
271−-- | /O(n)/ Adds a character to the end of a 'JSString'. This copies the
272−-- entire array in the process, unless fused. Subject to fusion.
273−-- Performs replacement on invalid scalar values.
274−snoc :: JSString -> Char -> JSString
275−snoc = coerce T.snoc
276− -- unstream (S.snoc (stream t) (safe c))
277−{-# INLINE [1] snoc #-}
278−
279−{-# RULES
280−"JSSTRING snoc -> fused" [~1] forall x c.
281− snoc x c = unstream (S.snoc (stream x) (safe c))
282−"JSSTRING snoc -> unfused" [1] forall x c.
283− unstream (S.snoc (stream x) (safe c)) = snoc x c
284− #-}
285−
286−-- | /O(n)/ Appends one 'JSString' to the other by copying both of them
287−-- into a new 'JSString'. Subject to fusion.
288−append :: JSString -> JSString -> JSString
289−append = coerce T.append
290−{-# INLINE [1] append #-}
291−
292−{-# RULES
293−"JSSTRING append -> fused" [~1] forall x1 x2.
294− append x1 x2 = unstream (S.append (stream x1) (stream x2))
295−"JSSTRING append -> unfused" [1] forall x1 x2.
296− unstream (S.append (stream x1) (stream x2)) = append x1 x2
297− #-}
298−
299−-- | /O(1)/ Returns the first character of a 'JSString', which must be
300−-- non-empty. Subject to fusion.
301−head :: JSString -> Char
302−head = coerce T.head
303−{-# INLINE [1] head #-}
304−
305−{-# RULES
306−"JSSTRING head -> fused" [~1] forall x.
307− head x = S.head (stream x)
308−"JSSTRING head -> unfused" [1] forall x.
309− S.head (stream x) = head x
310− #-}
311−
312−
313−-- | /O(1)/ Returns the first character and rest of a 'JSString', or
314−-- 'Nothing' if empty. Subject to fusion.
315−uncons :: JSString -> Maybe (Char, JSString)
316−uncons = coerce T.uncons
317−{-# INLINE [1] uncons #-}
318−
319−-- | Lifted from Control.Arrow and specialized.
320−second :: (b -> c) -> (a,b) -> (a,c)
321−second f (a, b) = (a, f b)
322−
323−-- | /O(1)/ Returns the last character of a 'JSString', which must be
324−-- non-empty. Subject to fusion.
325−last :: JSString -> Char
326−last = coerce T.last
327−{-# INLINE [1] last #-}
328−
329−{-# RULES
330−"JSSTRING last -> fused" [~1] forall x.
331− last x = S.last (stream x)
332−"JSSTRING last -> unfused" [1] forall x.
333− S.last (stream x) = last x
334− #-}
335−
336−-- | /O(1)/ Returns all characters after the head of a 'JSString', which
337−-- must be non-empty. Subject to fusion.
338−tail :: JSString -> JSString
339−tail = coerce T.tail
340−{-# INLINE [1] tail #-}
341−
342−{-# RULES
343−"JSSTRING tail -> fused" [~1] forall x.
344− tail x = unstream (S.tail (stream x))
345−"JSSTRING tail -> unfused" [1] forall x.
346− unstream (S.tail (stream x)) = tail x
347− #-}
348−
349−-- | /O(1)/ Returns all but the last character of a 'JSString', which must
350−-- be non-empty. Subject to fusion.
351−init :: JSString -> JSString
352−init = coerce T.init
353−{-# INLINE [1] init #-}
354−
355−{-# RULES
356−"JSSTRING init -> fused" [~1] forall t.
357− init t = unstream (S.init (stream t))
358−"JSSTRING init -> unfused" [1] forall t.
359− unstream (S.init (stream t)) = init t
360− #-}
361−
362−-- | /O(1)/ Tests whether a 'JSString' is empty or not. Subject to
363−-- fusion.
364−null :: JSString -> Bool
365−null = coerce T.null
366−{-# INLINE [1] null #-}
367−
368−{-# RULES
369−"JSSTRING null -> fused" [~1] forall t.
370− null t = S.null (stream t)
371−"JSSTRING null -> unfused" [1] forall t.
372− S.null (stream t) = null t
373− #-}
374−
375−-- | /O(n)/ Returns the number of characters in a 'JSString'.
376−-- Subject to fusion.
377−length :: JSString -> Int
378−length = coerce T.length
379−{-# INLINE [1] length #-}
380−
381−{-# RULES
382−"JSSTRING length -> fused" [~1] forall x.
383− length x = S.length (stream x)
384−"JSSTRING length -> unfused" [1] forall x.
385− S.length (stream x) = length x
386− #-}
387−
388−-- | /O(n)/ Compare the count of characters in a 'JSString' to a number.
389−-- Subject to fusion.
390−--
391−-- This function gives the same answer as comparing against the result
392−-- of 'length', but can short circuit if the count of characters is
393−-- greater than the number, and hence be more efficient.
394−compareLength :: JSString -> Int -> Ordering
395−compareLength = coerce T.compareLength
396−{-# INLINE [1] compareLength #-}
397−
398−{-# RULES
399−"JSSTRING compareN/length -> compareLength" [~1] forall t n.
400− compare (length t) n = compareLength t n
401− #-}
402−
403−{-# RULES
404−"JSSTRING ==N/length -> compareLength/==EQ" [~1] forall t n.
405− (==) (length t) n = compareLength t n == EQ
406− #-}
407−
408−{-# RULES
409−"JSSTRING /=N/length -> compareLength//=EQ" [~1] forall t n.
410− (/=) (length t) n = compareLength t n /= EQ
411− #-}
412−
413−{-# RULES
414−"JSSTRING <N/length -> compareLength/==LT" [~1] forall t n.
415− (<) (length t) n = compareLength t n == LT
416− #-}
417−
418−{-# RULES
419−"JSSTRING <=N/length -> compareLength//=GT" [~1] forall t n.
420− (<=) (length t) n = compareLength t n /= GT
421− #-}
422−
423−{-# RULES
424−"JSSTRING >N/length -> compareLength/==GT" [~1] forall t n.
425− (>) (length t) n = compareLength t n == GT
426− #-}
427−
428−{-# RULES
429−"JSSTRING >=N/length -> compareLength//=LT" [~1] forall t n.
430− (>=) (length t) n = compareLength t n /= LT
431− #-}
432−
433−-- -----------------------------------------------------------------------------
434−-- * Transformations
435−-- | /O(n)/ 'map' @f@ @t@ is the 'JSString' obtained by applying @f@ to
436−-- each element of @t@. Subject to fusion. Performs replacement on
437−-- invalid scalar values.
438−map :: (Char -> Char) -> JSString -> JSString
439−map = coerce T.map
440−{-# INLINE [1] map #-}
441−
442−-- | /O(n)/ The 'intercalate' function takes a 'JSString' and a list of
443−-- 'JSString's and concatenates the list after interspersing the first
444−-- argument between each element of the list.
445−intercalate :: JSString -> [JSString] -> JSString
446−intercalate = coerce T.intercalate
447−{-# INLINE [1] intercalate #-}
448−
449−-- | /O(n)/ The 'intersperse' function takes a character and places it
450−-- between the characters of a 'JSString'. Subject to fusion. Performs
451−-- replacement on invalid scalar values.
452−intersperse :: Char -> JSString -> JSString
453−intersperse = coerce T.intersperse
454−{-# INLINE [1] intersperse #-}
455−
456−{-# RULES
457−"JSSTRING intersperse -> fused" [~1] forall c x.
458− intersperse c x = unstream (S.intersperse (safe c) (stream x))
459−"JSSTRING intersperse -> unfused" [1] forall c x.
460− unstream (S.intersperse (safe c) (stream x)) = intersperse c x
461− #-}
462−
463−-- | /O(n)/ Reverse the characters of a string. Subject to fusion.
464−reverse :: JSString -> JSString
465−reverse = coerce T.reverse
466−{-# INLINE [1] reverse #-}
467−
468−{-# RULES
469−"JSSTRING reverse -> fused" [~1] forall x.
470− reverse x = S.reverse (stream x)
471−"JSSTRING reverse -> unfused" [1] forall x.
472− S.reverse (stream x) = reverse x
473− #-}
474−
475−-- | /O(m+n)/ Replace every non-overlapping occurrence of @needle@ in
476−-- @haystack@ with @replacement@.
477−--
478−-- This function behaves as though it was defined as follows:
479−--
480−-- @
481−-- replace needle replacement haystack =
482−-- 'intercalate' replacement ('splitOn' needle haystack)
483−-- @
484−--
485−-- As this suggests, each occurrence is replaced exactly once. So if
486−-- @needle@ occurs in @replacement@, that occurrence will /not/ itself
487−-- be replaced recursively:
488−--
489−-- > replace "oo" "foo" "oo" == "foo"
490−--
491−-- In cases where several instances of @needle@ overlap, only the
492−-- first one will be replaced:
493−--
494−-- > replace "ofo" "bar" "ofofo" == "barfo"
495−--
496−-- In (unlikely) bad cases, this function's time complexity degrades
497−-- towards /O(n*m)/.
498−replace :: JSString
499− -- ^ @needle@ to search for. If this string is empty, an
500− -- error will occur.
501− -> JSString
502− -- ^ @replacement@ to replace @needle@ with.
503− -> JSString
504− -- ^ @haystack@ in which to search.
505− -> JSString
506−replace = coerce T.replace
507−{-# INLINE replace #-}
508−
509−-- ----------------------------------------------------------------------------
510−-- ** Case conversions (folds)
511−
512−-- $case
513−--
514−-- When case converting 'JSString' values, do not use combinators like
515−-- @map toUpper@ to case convert each character of a string
516−-- individually, as this gives incorrect results according to the
517−-- rules of some writing systems. The whole-string case conversion
518−-- functions from this module, such as @toUpper@, obey the correct
519−-- case conversion rules. As a result, these functions may map one
520−-- input character to two or three output characters. For examples,
521−-- see the documentation of each function.
522−--
523−-- /Note/: In some languages, case conversion is a locale- and
524−-- context-dependent operation. The case conversion functions in this
525−-- module are /not/ locale sensitive. Programs that require locale
526−-- sensitivity should use appropriate versions of the
527−-- <http://hackage.haskell.org/package/text-icu-0.6.3.7/docs/Data-Text-ICU.html#g:4 case mapping functions from the text-icu package >.
528−
529−-- | /O(n)/ Convert a string to folded case. Subject to fusion.
530−--
531−-- This function is mainly useful for performing caseless (also known
532−-- as case insensitive) string comparisons.
533−--
534−-- A string @x@ is a caseless match for a string @y@ if and only if:
535−--
536−-- @toCaseFold x == toCaseFold y@
537−--
538−-- The result string may be longer than the input string, and may
539−-- differ from applying 'toLower' to the input string. For instance,
540−-- the Armenian small ligature \"ﬓ\" (men now, U+FB13) is case
541−-- folded to the sequence \"մ\" (men, U+0574) followed by
542−-- \"ն\" (now, U+0576), while the Greek \"µ\" (micro sign,
543−-- U+00B5) is case folded to \"μ\" (small letter mu, U+03BC)
544−-- instead of itself.
545−toCaseFold :: JSString -> JSString
546−toCaseFold = coerce T.toCaseFold
547−{-# INLINE [0] toCaseFold #-}
548−
549−-- | /O(n)/ Convert a string to lower case, using simple case
550−-- conversion. Subject to fusion.
551−--
552−-- The result string may be longer than the input string. For
553−-- instance, \"İ\" (Latin capital letter I with dot above,
554−-- U+0130) maps to the sequence \"i\" (Latin small letter i, U+0069)
555−-- followed by \" ̇\" (combining dot above, U+0307).
556−toLower :: JSString -> JSString
557−toLower = coerce T.toLower
558−{-# INLINE [1] toLower #-}
559−
560−{-# RULES
561−"JSSTRING toLower -> fused" [~1] forall x.
562− toLower x = unstream (S.toLower (stream x))
563−"JSSTRING toLower -> unfused" [1] forall x.
564− unstream (S.toLower (stream x)) = toLower x
565− #-}
566−
567−-- | /O(n)/ Convert a string to upper case, using simple case
568−-- conversion. Subject to fusion.
569−--
570−-- The result string may be longer than the input string. For
571−-- instance, the German \"ß\" (eszett, U+00DF) maps to the
572−-- two-letter sequence \"SS\".
573−toUpper :: JSString -> JSString
574−toUpper = coerce T.toUpper
575−{-# INLINE [1] toUpper #-}
576−
577−{-# RULES
578−"JSSTRING toUpper -> fused" [~1] forall x.
579− toUpper x = unstream (S.toUpper(stream x))
580−"JSSTRING toUpper -> unfused" [1] forall x.
581− unstream (S.toUpper (stream x)) = toUpper x
582− #-}
583−
584−-- | /O(n)/ Convert a string to title case, using simple case
585−-- conversion. Subject to fusion.
586−--
587−-- The first letter of the input is converted to title case, as is
588−-- every subsequent letter that immediately follows a non-letter.
589−-- Every letter that immediately follows another letter is converted
590−-- to lower case.
591−--
592−-- The result string may be longer than the input string. For example,
593−-- the Latin small ligature fl (U+FB02) is converted to the
594−-- sequence Latin capital letter F (U+0046) followed by Latin small
595−-- letter l (U+006C).
596−--
597−-- /Note/: this function does not take language or culture specific
598−-- rules into account. For instance, in English, different style
599−-- guides disagree on whether the book name \"The Hill of the Red
600−-- Fox\" is correctly title cased—but this function will
601−-- capitalize /every/ word.
602−toTitle :: JSString -> JSString
603−toTitle = coerce T.toTitle
604−{-# INLINE toTitle #-}
605−
606−-- | /O(n)/ Left-justify a string to the given length, using the
607−-- specified fill character on the right. Subject to fusion.
608−-- Performs replacement on invalid scalar values.
609−--
610−-- Examples:
611−--
612−-- > justifyLeft 7 'x' "foo" == "fooxxxx"
613−-- > justifyLeft 3 'x' "foobar" == "foobar"
614−justifyLeft :: Int -> Char -> JSString -> JSString
615−justifyLeft = coerce T.justifyLeft
616−{-# INLINE [1] justifyLeft #-}
617−
618−{-# RULES
619−"JSSTRING justifyLeft -> fused" [~1] forall k c t.
620− justifyLeft k c t = unstream (S.justifyLeftI k c (stream t))
621−"JSSTRING justifyLeft -> unfused" [1] forall k c t.
622− unstream (S.justifyLeftI k c (stream t)) = justifyLeft k c t
623− #-}
624−
625−-- | /O(n)/ Right-justify a string to the given length, using the
626−-- specified fill character on the left. Performs replacement on
627−-- invalid scalar values.
628−--
629−-- Examples:
630−--
631−-- > justifyRight 7 'x' "bar" == "xxxxbar"
632−-- > justifyRight 3 'x' "foobar" == "foobar"
633−justifyRight :: Int -> Char -> JSString -> JSString
634−justifyRight = coerce T.justifyRight
635−{-# INLINE justifyRight #-}
636−
637−-- | /O(n)/ Center a string to the given length, using the specified
638−-- fill character on either side. Performs replacement on invalid
639−-- scalar values.
640−--
641−-- Examples:
642−--
643−-- > center 8 'x' "HS" = "xxxHSxxx"
644−center :: Int -> Char -> JSString -> JSString
645−center = coerce T.center
646−{-# INLINE center #-}
647−
648−-- | /O(n)/ The 'transpose' function transposes the rows and columns
649−-- of its 'JSString' argument. Note that this function uses 'pack',
650−-- 'unpack', and the list version of transpose, and is thus not very
651−-- efficient.
652−transpose :: [JSString] -> [JSString]
653−transpose = coerce T.transpose
654−
655−-- -----------------------------------------------------------------------------
656−-- * Reducing 'JSString's (folds)
657−
658−-- | /O(n)/ 'foldl', applied to a binary operator, a starting value
659−-- (typically the left-identity of the operator), and a 'JSString',
660−-- reduces the 'JSString' using the binary operator, from left to right.
661−-- Subject to fusion.
662−foldl :: (a -> Char -> a) -> a -> JSString -> a
663−foldl f = coerce (T.foldl f)
664−{-# INLINE foldl #-}
665−
666−-- | /O(n)/ A strict version of 'foldl'. Subject to fusion.
667−foldl' :: (a -> Char -> a) -> a -> JSString -> a
668−foldl' f = coerce (T.foldl' f)
669−{-# INLINE foldl' #-}
670−
671−-- | /O(n)/ A variant of 'foldl' that has no starting value argument,
672−-- and thus must be applied to a non-empty 'JSString'. Subject to fusion.
673−foldl1 :: (Char -> Char -> Char) -> JSString -> Char
674−foldl1 = coerce T.foldl1
675−{-# INLINE foldl1 #-}
676−
677−-- | /O(n)/ A strict version of 'foldl1'. Subject to fusion.
678−foldl1' :: (Char -> Char -> Char) -> JSString -> Char
679−foldl1' = coerce T.foldl1'
680−{-# INLINE foldl1' #-}
681−
682−-- | /O(n)/ 'foldr', applied to a binary operator, a starting value
683−-- (typically the right-identity of the operator), and a 'JSString',
684−-- reduces the 'JSString' using the binary operator, from right to left.
685−-- Subject to fusion.
686−foldr :: (Char -> a -> a) -> a -> JSString -> a
687−foldr f = coerce (T.foldr f)
688−{-# INLINE foldr #-}
689−
690−-- | /O(n)/ A variant of 'foldr' that has no starting value argument,
691−-- and thus must be applied to a non-empty 'JSString'. Subject to
692−-- fusion.
693−foldr1 :: (Char -> Char -> Char) -> JSString -> Char
694−foldr1 = coerce T.foldr1
695−{-# INLINE foldr1 #-}
696−
697−-- -----------------------------------------------------------------------------
698−-- ** Special folds
699−
700−-- | /O(n)/ Concatenate a list of 'JSString's.
701−concat :: [JSString] -> JSString
702−concat = coerce T.concat
703−
704−-- | /O(n)/ Map a function over a 'JSString' that results in a 'JSString', and
705−-- concatenate the results.
706−concatMap :: (Char -> JSString) -> JSString -> JSString
707−concatMap = coerce T.concatMap
708−{-# INLINE concatMap #-}
709−
710−-- | /O(n)/ 'any' @p@ @t@ determines whether any character in the
711−-- 'JSString' @t@ satisifes the predicate @p@. Subject to fusion.
712−any :: (Char -> Bool) -> JSString -> Bool
713−any = coerce T.any
714−{-# INLINE any #-}
715−
716−-- | /O(n)/ 'all' @p@ @t@ determines whether all characters in the
717−-- 'JSString' @t@ satisify the predicate @p@. Subject to fusion.
718−all :: (Char -> Bool) -> JSString -> Bool
719−all = coerce T.all
720−{-# INLINE all #-}
721−
722−-- | /O(n)/ 'maximum' returns the maximum value from a 'JSString', which
723−-- must be non-empty. Subject to fusion.
724−maximum :: JSString -> Char
725−maximum = coerce T.maximum
726−{-# INLINE maximum #-}
727−
728−-- | /O(n)/ 'minimum' returns the minimum value from a 'JSString', which
729−-- must be non-empty. Subject to fusion.
730−minimum :: JSString -> Char
731−minimum = coerce T.minimum
732−{-# INLINE minimum #-}
733−
734−-- -----------------------------------------------------------------------------
735−-- * Building 'JSString's
736−
737−-- | /O(n)/ 'scanl' is similar to 'foldl', but returns a list of
738−-- successive reduced values from the left. Subject to fusion.
739−-- Performs replacement on invalid scalar values.
740−--
741−-- > scanl f z [x1, x2, ...] == [z, z `f` x1, (z `f` x1) `f` x2, ...]
742−--
743−-- Note that
744−--
745−-- > last (scanl f z xs) == foldl f z xs.
746−scanl :: (Char -> Char -> Char) -> Char -> JSString -> JSString
747−scanl = coerce T.scanl
748−{-# INLINE scanl #-}
749−
750−-- | /O(n)/ 'scanl1' is a variant of 'scanl' that has no starting
751−-- value argument. Subject to fusion. Performs replacement on
752−-- invalid scalar values.
753−--
754−-- > scanl1 f [x1, x2, ...] == [x1, x1 `f` x2, ...]
755−scanl1 :: (Char -> Char -> Char) -> JSString -> JSString
756−scanl1 = coerce T.scanl1
757−{-# INLINE scanl1 #-}
758−
759−-- | /O(n)/ 'scanr' is the right-to-left dual of 'scanl'. Performs
760−-- replacement on invalid scalar values.
761−--
762−-- > scanr f v == reverse . scanl (flip f) v . reverse
763−scanr :: (Char -> Char -> Char) -> Char -> JSString -> JSString
764−scanr = coerce T.scanr
765−{-# INLINE scanr #-}
766−
767−-- | /O(n)/ 'scanr1' is a variant of 'scanr' that has no starting
768−-- value argument. Subject to fusion. Performs replacement on
769−-- invalid scalar values.
770−scanr1 :: (Char -> Char -> Char) -> JSString -> JSString
771−scanr1 = coerce T.scanr1
772−{-# INLINE scanr1 #-}
773−
774−-- | /O(n)/ Like a combination of 'map' and 'foldl''. Applies a
775−-- function to each element of a 'JSString', passing an accumulating
776−-- parameter from left to right, and returns a final 'JSString'. Performs
777−-- replacement on invalid scalar values.
778−mapAccumL :: (a -> Char -> (a,Char)) -> a -> JSString -> (a, JSString)
779−mapAccumL f = coerce (T.mapAccumL f)
780−{-# INLINE mapAccumL #-}
781−
782−-- | The 'mapAccumR' function behaves like a combination of 'map' and
783−-- a strict 'foldr'; it applies a function to each element of a
784−-- 'JSString', passing an accumulating parameter from right to left, and
785−-- returning a final value of this accumulator together with the new
786−-- 'JSString'.
787−-- Performs replacement on invalid scalar values.
788−mapAccumR :: (a -> Char -> (a,Char)) -> a -> JSString -> (a, JSString)
789−mapAccumR f = coerce (T.mapAccumR f)
790−{-# INLINE mapAccumR #-}
791−
792−-- -----------------------------------------------------------------------------
793−-- ** Generating and unfolding 'JSString's
794−
795−-- | /O(n*m)/ 'replicate' @n@ @t@ is a 'JSString' consisting of the input
796−-- @t@ repeated @n@ times.
797−replicate :: Int -> JSString -> JSString
798−replicate = coerce T.replicate
799−{-# INLINE [1] replicate #-}
800−
801−-- | /O(n)/, where @n@ is the length of the result. The 'unfoldr'
802−-- function is analogous to the List 'L.unfoldr'. 'unfoldr' builds a
803−-- 'JSString' from a seed value. The function takes the element and
804−-- returns 'Nothing' if it is done producing the 'JSString', otherwise
805−-- 'Just' @(a,b)@. In this case, @a@ is the next 'Char' in the
806−-- string, and @b@ is the seed value for further production. Subject
807−-- to fusion. Performs replacement on invalid scalar values.
808−unfoldr :: (a -> Maybe (Char,a)) -> a -> JSString
809−unfoldr f = coerce (T.unfoldr f)
810−{-# INLINE unfoldr #-}
811−
812−-- | /O(n)/ Like 'unfoldr', 'unfoldrN' builds a 'JSString' from a seed
813−-- value. However, the length of the result should be limited by the
814−-- first argument to 'unfoldrN'. This function is more efficient than
815−-- 'unfoldr' when the maximum length of the result is known and
816−-- correct, otherwise its performance is similar to 'unfoldr'. Subject
817−-- to fusion. Performs replacement on invalid scalar values.
818−unfoldrN :: Int -> (a -> Maybe (Char,a)) -> a -> JSString
819−unfoldrN n f = coerce (T.unfoldrN n f)
820−{-# INLINE unfoldrN #-}
821−
822−-- -----------------------------------------------------------------------------
823−-- * Substrings
824−
825−-- | /O(n)/ 'take' @n@, applied to a 'JSString', returns the prefix of the
826−-- 'JSString' of length @n@, or the 'JSString' itself if @n@ is greater than
827−-- the length of the JSString. Subject to fusion.
828−take :: Int -> JSString -> JSString
829−take = coerce T.take
830−{-# INLINE [1] take #-}
831−{-
832−iterN :: Int -> JSString -> Int
833−iterN n t@(Text _arr _off len) = loop 0 0
834− where loop !i !cnt
835− | i >= len || cnt >= n = i
836− | otherwise = loop (i+d) (cnt+1)
837− where d = iter_ t i
838−-}
839−{-# RULES
840−"JSSTRING take -> fused" [~1] forall n t.
841− take n t = unstream (S.take n (stream t))
842−"JSSTRING take -> unfused" [1] forall n t.
843− unstream (S.take n (stream t)) = take n t
844− #-}
845−
846−-- | /O(n)/ 'takeEnd' @n@ @t@ returns the suffix remaining after
847−-- taking @n@ characters from the end of @t@.
848−--
849−-- Examples:
850−--
851−-- > takeEnd 3 "foobar" == "bar"
852−takeEnd :: Int -> JSString -> JSString
853−takeEnd = coerce T.takeEnd
854−
855−-- | /O(n)/ 'drop' @n@, applied to a 'JSString', returns the suffix of the
856−-- 'JSString' after the first @n@ characters, or the empty 'JSString' if @n@
857−-- is greater than the length of the 'JSString'. Subject to fusion.
858−drop :: Int -> JSString -> JSString
859−drop = coerce T.drop
860−{-# INLINE [1] drop #-}
861−
862−{-# RULES
863−"JSSTRING drop -> fused" [~1] forall n t.
864− drop n t = unstream (S.drop n (stream t))
865−"JSSTRING drop -> unfused" [1] forall n t.
866− unstream (S.drop n (stream t)) = drop n t
867− #-}
868−
869−-- | /O(n)/ 'dropEnd' @n@ @t@ returns the prefix remaining after
870−-- dropping @n@ characters from the end of @t@.
871−--
872−-- Examples:
873−--
874−-- > dropEnd 3 "foobar" == "foo"
875−dropEnd :: Int -> JSString -> JSString
876−dropEnd = coerce T.dropEnd
877−
878−-- | /O(n)/ 'takeWhile', applied to a predicate @p@ and a 'JSString',
879−-- returns the longest prefix (possibly empty) of elements that
880−-- satisfy @p@. Subject to fusion.
881−takeWhile :: (Char -> Bool) -> JSString -> JSString
882−takeWhile = coerce T.takeWhile
883−{-# INLINE [1] takeWhile #-}
884−
885−{-# RULES
886−"TEXT takeWhile -> fused" [~1] forall p t.
887− takeWhile p t = unstream (S.takeWhile p (stream t))
888−"TEXT takeWhile -> unfused" [1] forall p t.
889− unstream (S.takeWhile p (stream t)) = takeWhile p t
890− #-}
891−
892−-- | /O(n)/ 'dropWhile' @p@ @t@ returns the suffix remaining after
893−-- 'takeWhile' @p@ @t@. Subject to fusion.
894−dropWhile :: (Char -> Bool) -> JSString -> JSString
895−dropWhile = coerce T.dropWhile
896−{-# INLINE [1] dropWhile #-}
897−
898−{-# RULES
899−"TEXT dropWhile -> fused" [~1] forall p t.
900− dropWhile p t = unstream (S.dropWhile p (stream t))
901−"TEXT dropWhile -> unfused" [1] forall p t.
902− unstream (S.dropWhile p (stream t)) = dropWhile p t
903− #-}
904−
905−-- | /O(n)/ 'dropWhileEnd' @p@ @t@ returns the prefix remaining after
906−-- dropping characters that fail the predicate @p@ from the end of
907−-- @t@. Subject to fusion.
908−-- Examples:
909−--
910−-- > dropWhileEnd (=='.') "foo..." == "foo"
911−dropWhileEnd :: (Char -> Bool) -> JSString -> JSString
912−dropWhileEnd = coerce T.dropWhileEnd
913−{-# INLINE [1] dropWhileEnd #-}
914−
915−{-# RULES
916−"TEXT dropWhileEnd -> fused" [~1] forall p t.
917− dropWhileEnd p t = S.reverse (S.dropWhile p (S.reverseStream t))
918−"TEXT dropWhileEnd -> unfused" [1] forall p t.
919− S.reverse (S.dropWhile p (S.reverseStream t)) = dropWhileEnd p t
920− #-}
921−
922−-- | /O(n)/ 'dropAround' @p@ @t@ returns the substring remaining after
923−-- dropping characters that fail the predicate @p@ from both the
924−-- beginning and end of @t@. Subject to fusion.
925−dropAround :: (Char -> Bool) -> JSString -> JSString
926−dropAround = coerce T.dropAround
927−{-# INLINE [1] dropAround #-}
928−
929−-- | /O(n)/ Remove leading white space from a string. Equivalent to:
930−--
931−-- > dropWhile isSpace
932−stripStart :: JSString -> JSString
933−stripStart = coerce T.stripStart
934−{-# INLINE [1] stripStart #-}
935−
936−-- | /O(n)/ Remove trailing white space from a string. Equivalent to:
937−--
938−-- > dropWhileEnd isSpace
939−stripEnd :: JSString -> JSString
940−stripEnd = coerce T.stripEnd
941−{-# INLINE [1] stripEnd #-}
942−
943−-- | /O(n)/ Remove leading and trailing white space from a string.
944−-- Equivalent to:
945−--
946−-- > dropAround isSpace
947−strip :: JSString -> JSString
948−strip = coerce T.strip
949−{-# INLINE [1] strip #-}
950−
951−-- | /O(n)/ 'splitAt' @n t@ returns a pair whose first element is a
952−-- prefix of @t@ of length @n@, and whose second is the remainder of
953−-- the string. It is equivalent to @('take' n t, 'drop' n t)@.
954−splitAt :: Int -> JSString -> (JSString, JSString)
955−splitAt = coerce T.splitAt
956−{-# INLINE splitAt #-}
957−
958−-- | /O(n)/ 'span', applied to a predicate @p@ and text @t@, returns
959−-- a pair whose first element is the longest prefix (possibly empty)
960−-- of @t@ of elements that satisfy @p@, and whose second is the
961−-- remainder of the list.
962−span :: (Char -> Bool) -> JSString -> (JSString, JSString)
963−span = coerce T.span
964−{-# INLINE span #-}
965−
966−-- | /O(n)/ 'break' is like 'span', but the prefix returned is
967−-- over elements that fail the predicate @p@.
968−break :: (Char -> Bool) -> JSString -> (JSString, JSString)
969−break = coerce T.break
970−{-# INLINE break #-}
971−
972−-- | /O(n)/ Group characters in a string according to a predicate.
973−groupBy :: (Char -> Char -> Bool) -> JSString -> [JSString]
974−groupBy = coerce T.groupBy
975−
976−-- | /O(n)/ Group characters in a string by equality.
977−group :: JSString -> [JSString]
978−group = coerce T.group
979−{-# INLINE group #-}
980−
981−group' :: JSString -> [JSString]
982−group' = coerce T.group
983−{-# INLINE group' #-}
984−
985−-- | /O(n^2)/ Return all initial segments of the given 'JSString', shortest
986−-- first.
987−inits :: JSString -> [JSString]
988−inits = coerce T.inits
989−
990−-- | /O(n^2)/ Return all final segments of the given 'JSString', longest
991−-- first.
992−tails :: JSString -> [JSString]
993−tails = coerce T.tails
994−
995−-- $split
996−--
997−-- Splitting functions in this library do not perform character-wise
998−-- copies to create substrings; they just construct new 'JSString's that
999−-- are slices of the original.
1000−
1001−-- | /O(m+n)/ Break a 'JSString' into pieces separated by the first 'JSString'
1002−-- argument (which cannot be empty), consuming the delimiter. An empty
1003−-- delimiter is invalid, and will cause an error to be raised.
1004−--
1005−-- Examples:
1006−--
1007−-- > splitOn "\r\n" "a\r\nb\r\nd\r\ne" == ["a","b","d","e"]
1008−-- > splitOn "aaa" "aaaXaaaXaaaXaaa" == ["","X","X","X",""]
1009−-- > splitOn "x" "x" == ["",""]
1010−--
1011−-- and
1012−--
1013−-- > intercalate s . splitOn s == id
1014−-- > splitOn (singleton c) == split (==c)
1015−--
1016−-- (Note: the string @s@ to split on above cannot be empty.)
1017−--
1018−-- In (unlikely) bad cases, this function's time complexity degrades
1019−-- towards /O(n*m)/.
1020−splitOn :: JSString
1021− -- ^ String to split on. If this string is empty, an error
1022− -- will occur.
1023− -> JSString
1024− -- ^ Input text.
1025− -> [JSString]
1026−splitOn = coerce T.splitOn
1027−{-# INLINE [1] splitOn #-}
1028−
1029−-- RULES
1030−-- "JSSTRING splitOn/singleton -> split/==" [~1] forall c t.
1031−-- splitOn (singleton c) t = split (==c) t
1032−--
1033−
1034−splitOn' :: JSString
1035− -- ^ String to split on. If this string is empty, an error
1036− -- will occur.
1037− -> JSString
1038− -- ^ Input text.
1039− -> [JSString]
1040−splitOn' = coerce T.splitOn
1041−{-# NOINLINE splitOn' #-}
1042−--- {-# INLINE [1] splitOn' #-}
1043−
1044−-- | /O(n)/ Splits a 'JSString' into components delimited by separators,
1045−-- where the predicate returns True for a separator element. The
1046−-- resulting components do not contain the separators. Two adjacent
1047−-- separators result in an empty component in the output. eg.
1048−--
1049−-- > split (=='a') "aabbaca" == ["","","bb","c",""]
1050−-- > split (=='a') "" == [""]
1051−split :: (Char -> Bool) -> JSString -> [JSString]
1052−split = coerce T.split
1053−{-# INLINE split #-}
1054−
1055−-- | /O(n)/ Splits a 'JSString' into components of length @k@. The last
1056−-- element may be shorter than the other chunks, depending on the
1057−-- length of the input. Examples:
1058−--
1059−-- > chunksOf 3 "foobarbaz" == ["foo","bar","baz"]
1060−-- > chunksOf 4 "haskell.org" == ["hask","ell.","org"]
1061−chunksOf :: Int -> JSString -> [JSString]
1062−chunksOf = coerce T.chunksOf
1063−{-# INLINE chunksOf #-}
1064−
1065−-- | /O(n)/ Splits a 'JSString' into components of length @k@. The last
1066−-- element may be shorter than the other chunks, depending on the
1067−-- length of the input. Examples:
1068−--
1069−-- > chunksOf 3 "foobarbaz" == ["foo","bar","baz"]
1070−-- > chunksOf 4 "haskell.org" == ["hask","ell.","org"]
1071−chunksOf' :: Int -> JSString -> [JSString]
1072−chunksOf' = coerce T.chunksOf
1073−{-# INLINE chunksOf' #-}
1074−
1075−-- ----------------------------------------------------------------------------
1076−-- * Searching
1077−
1078−-------------------------------------------------------------------------------
1079−-- ** Searching with a predicate
1080−
1081−-- | /O(n)/ The 'find' function takes a predicate and a 'JSString', and
1082−-- returns the first element matching the predicate, or 'Nothing' if
1083−-- there is no such element.
1084−find :: (Char -> Bool) -> JSString -> Maybe Char
1085−find = coerce T.find
1086−{-# INLINE find #-}
1087−
1088−-- | /O(n)/ The 'partition' function takes a predicate and a 'JSString',
1089−-- and returns the pair of 'JSString's with elements which do and do not
1090−-- satisfy the predicate, respectively; i.e.
1091−--
1092−-- > partition p t == (filter p t, filter (not . p) t)
1093−partition :: (Char -> Bool) -> JSString -> (JSString, JSString)
1094−partition = coerce T.partition
1095−{-# INLINE partition #-}
1096−
1097−-- | /O(n)/ 'filter', applied to a predicate and a 'JSString',
1098−-- returns a 'JSString' containing those characters that satisfy the
1099−-- predicate.
1100−filter :: (Char -> Bool) -> JSString -> JSString
1101−filter = coerce T.filter
1102−{-# INLINE filter #-}
1103−
1104−-- | /O(n+m)/ Find the first instance of @needle@ (which must be
1105−-- non-'null') in @haystack@. The first element of the returned tuple
1106−-- is the prefix of @haystack@ before @needle@ is matched. The second
1107−-- is the remainder of @haystack@, starting with the match.
1108−--
1109−-- Examples:
1110−--
1111−-- > breakOn "::" "a::b::c" ==> ("a", "::b::c")
1112−-- > breakOn "/" "foobar" ==> ("foobar", "")
1113−--
1114−-- Laws:
1115−--
1116−-- > append prefix match == haystack
1117−-- > where (prefix, match) = breakOn needle haystack
1118−--
1119−-- If you need to break a string by a substring repeatedly (e.g. you
1120−-- want to break on every instance of a substring), use 'breakOnAll'
1121−-- instead, as it has lower startup overhead.
1122−--
1123−-- In (unlikely) bad cases, this function's time complexity degrades
1124−-- towards /O(n*m)/.
1125−breakOn :: JSString -> JSString -> (JSString, JSString)
1126−breakOn = coerce T.breakOn
1127−{-# INLINE breakOn #-}
1128−
1129−-- | /O(n+m)/ Similar to 'breakOn', but searches from the end of the
1130−-- string.
1131−--
1132−-- The first element of the returned tuple is the prefix of @haystack@
1133−-- up to and including the last match of @needle@. The second is the
1134−-- remainder of @haystack@, following the match.
1135−--
1136−-- > breakOnEnd "::" "a::b::c" ==> ("a::b::", "c")
1137−breakOnEnd :: JSString -> JSString -> (JSString, JSString)
1138−breakOnEnd = coerce T.breakOnEnd
1139−{-# INLINE breakOnEnd #-}
1140−
1141−-- | /O(n+m)/ Find all non-overlapping instances of @needle@ in
1142−-- @haystack@. Each element of the returned list consists of a pair:
1143−--
1144−-- * The entire string prior to the /k/th match (i.e. the prefix)
1145−--
1146−-- * The /k/th match, followed by the remainder of the string
1147−--
1148−-- Examples:
1149−--
1150−-- > breakOnAll "::" ""
1151−-- > ==> []
1152−-- > breakOnAll "/" "a/b/c/"
1153−-- > ==> [("a", "/b/c/"), ("a/b", "/c/"), ("a/b/c", "/")]
1154−--
1155−-- In (unlikely) bad cases, this function's time complexity degrades
1156−-- towards /O(n*m)/.
1157−--
1158−-- The @needle@ parameter may not be empty.
1159−breakOnAll :: JSString -- ^ @needle@ to search for
1160− -> JSString -- ^ @haystack@ in which to search
1161− -> [(JSString, JSString)]
1162−breakOnAll = coerce T.breakOnAll
1163−{-# INLINE breakOnAll #-}
1164−
1165−breakOnAll' :: JSString -- ^ @needle@ to search for
1166− -> JSString -- ^ @haystack@ in which to search
1167− -> [(JSString, JSString)]
1168−breakOnAll' = coerce T.breakOnAll
1169−{-# INLINE breakOnAll' #-}
1170−
1171−-------------------------------------------------------------------------------
1172−-- ** Indexing 'JSString's
1173−
1174−-- $index
1175−--
1176−-- If you think of a 'JSString' value as an array of 'Char' values (which
1177−-- it is not), you run the risk of writing inefficient code.
1178−--
1179−-- An idiom that is common in some languages is to find the numeric
1180−-- offset of a character or substring, then use that number to split
1181−-- or trim the searched string. With a 'JSString' value, this approach
1182−-- would require two /O(n)/ operations: one to perform the search, and
1183−-- one to operate from wherever the search ended.
1184−--
1185−-- For example, suppose you have a string that you want to split on
1186−-- the substring @\"::\"@, such as @\"foo::bar::quux\"@. Instead of
1187−-- searching for the index of @\"::\"@ and taking the substrings
1188−-- before and after that index, you would instead use @breakOnAll \"::\"@.
1189−
1190−-- | /O(n)/ 'JSString' index (subscript) operator, starting from 0.
1191−index :: JSString -> Int -> Char
1192−index = coerce T.index
1193−{-# INLINE index #-}
1194−
1195−-- | /O(n)/ The 'findIndex' function takes a predicate and a 'JSString'
1196−-- and returns the index of the first element in the 'JSString' satisfying
1197−-- the predicate. Subject to fusion.
1198−findIndex :: (Char -> Bool) -> JSString -> Maybe Int
1199−findIndex = coerce T.findIndex
1200−{-# INLINE findIndex #-}
1201−
1202−-- | /O(n+m)/ The 'count' function returns the number of times the
1203−-- query string appears in the given 'JSString'. An empty query string is
1204−-- invalid, and will cause an error to be raised.
1205−--
1206−-- In (unlikely) bad cases, this function's time complexity degrades
1207−-- towards /O(n*m)/.
1208−count :: JSString -> JSString -> Int
1209−count = coerce T.count
1210−{-# INLINE [1] count #-}
1211−
1212−-- RULES
1213−-- "JSSTRING count/singleton -> countChar" [~1] forall c t.
1214−-- count (singleton c) t = countChar c t
1215−--
1216−
1217−-------------------------------------------------------------------------------
1218−-- * Zipping
1219−
1220−-- | /O(n)/ 'zip' takes two 'JSString's and returns a list of
1221−-- corresponding pairs of bytes. If one input 'JSString' is short,
1222−-- excess elements of the longer 'JSString' are discarded. This is
1223−-- equivalent to a pair of 'unpack' operations.
1224−zip :: JSString -> JSString -> [(Char,Char)]
1225−zip = coerce T.zip
1226−{-# INLINE [0] zip #-}
1227−
1228−-- | /O(n)/ 'zipWith' generalises 'zip' by zipping with the function
1229−-- given as the first argument, instead of a tupling function.
1230−-- Performs replacement on invalid scalar values.
1231−zipWith :: (Char -> Char -> Char) -> JSString -> JSString -> JSString
1232−zipWith = coerce T.zipWith
1233−{-# INLINE [0] zipWith #-}
1234−
1235−-- | /O(n)/ Breaks a 'JSString' up into a list of words, delimited by 'Char's
1236−-- representing white space.
1237−words :: JSString -> [JSString]
1238−words = coerce T.words
1239−{-# INLINE words #-}
1240−
1241−-- fixme: strict words' that allocates the whole list in one go
1242−words' :: JSString -> [JSString]
1243−words' = coerce T.words
1244−{-# INLINE words' #-}
1245−
1246−-- | /O(n)/ Breaks a 'JSString' up into a list of 'JSString's at
1247−-- newline 'Char's. The resulting strings do not contain newlines.
1248−lines :: JSString -> [JSString]
1249−lines = coerce T.lines
1250−{-# INLINE lines #-}
1251−
1252−lines' :: JSString -> [JSString]
1253−lines' = coerce T.lines
1254−{-# INLINE lines' #-}
1255−
1256−{-
1257−-- | /O(n)/ Portably breaks a 'JSString' up into a list of 'JSString's at line
1258−-- boundaries.
1259−--
1260−-- A line boundary is considered to be either a line feed, a carriage
1261−-- return immediately followed by a line feed, or a carriage return.
1262−-- This accounts for both Unix and Windows line ending conventions,
1263−-- and for the old convention used on Mac OS 9 and earlier.
1264−lines' :: Text -> [Text]
1265−lines' ps | null ps = []
1266− | otherwise = h : case uncons t of
1267− Nothing -> []
1268− Just (c,t')
1269− | c == '\n' -> lines t'
1270− | c == '\r' -> case uncons t' of
1271− Just ('\n',t'') -> lines t''
1272− _ -> lines t'
1273− where (h,t) = span notEOL ps
1274− notEOL c = c /= '\n' && c /= '\r'
1275−
1276−-}
1277−
1278−-- | /O(n)/ Joins lines, after appending a terminating newline to
1279−-- each.
1280−unlines :: [JSString] -> JSString
1281−unlines = coerce T.unlines
1282−{-# INLINE unlines #-}
1283−
1284−-- | /O(n)/ Joins words using single space characters.
1285−unwords :: [JSString] -> JSString
1286−unwords = coerce T.unwords
1287−{-# INLINE unwords #-}
1288−
1289−-- | /O(n)/ The 'isPrefixOf' function takes two 'JSString's and returns
1290−-- 'True' iff the first is a prefix of the second. Subject to fusion.
1291−isPrefixOf :: JSString -> JSString -> Bool
1292−isPrefixOf = coerce T.isPrefixOf
1293−{-# INLINE [1] isPrefixOf #-}
1294−
1295−{-# RULES
1296−"JSSTRING isPrefixOf -> fused" [~1] forall x y.
1297− isPrefixOf x y = S.isPrefixOf (stream x) (stream y)
1298−"JSSTRING isPrefixOf -> unfused" [1] forall x y.
1299− S.isPrefixOf (stream x) (stream y) = isPrefixOf x y
1300− #-}
1301−
1302−-- | /O(n)/ The 'isSuffixOf' function takes two 'JSString's and returns
1303−-- 'True' iff the first is a suffix of the second.
1304−isSuffixOf :: JSString -> JSString -> Bool
1305−isSuffixOf = coerce T.isSuffixOf
1306−{-# INLINE isSuffixOf #-}
1307−
1308−-- | The 'isInfixOf' function takes two 'JSString's and returns
1309−-- 'True' iff the first is contained, wholly and intact, anywhere
1310−-- within the second.
1311−--
1312−-- Complexity depends on how the JavaScript engine implements
1313−-- String.prototype.find.
1314−isInfixOf :: JSString -> JSString -> Bool
1315−isInfixOf = coerce T.isInfixOf
1316−{-# INLINE [1] isInfixOf #-}
1317−
1318−{-# RULES
1319−"JSSTRING isInfixOf/singleton -> S.elem/S.stream" [~1] forall n h.
1320− isInfixOf (singleton n) h = S.elem n (S.stream h)
1321− #-}
1322−
1323−-------------------------------------------------------------------------------
1324−-- * View patterns
1325−
1326−-- | /O(n)/ Return the suffix of the second string if its prefix
1327−-- matches the entire first string.
1328−--
1329−-- Examples:
1330−--
1331−-- > stripPrefix "foo" "foobar" == Just "bar"
1332−-- > stripPrefix "" "baz" == Just "baz"
1333−-- > stripPrefix "foo" "quux" == Nothing
1334−--
1335−-- This is particularly useful with the @ViewPatterns@ extension to
1336−-- GHC, as follows:
1337−--
1338−-- > {-# LANGUAGE ViewPatterns #-}
1339−-- > import Data.Text as T
1340−-- >
1341−-- > fnordLength :: JSString -> Int
1342−-- > fnordLength (stripPrefix "fnord" -> Just suf) = T.length suf
1343−-- > fnordLength _ = -1
1344−stripPrefix :: JSString -> JSString -> Maybe JSString
1345−stripPrefix = coerce T.stripPrefix
1346−{-# INLINE stripPrefix #-}
1347−
1348−-- | /O(n)/ Find the longest non-empty common prefix of two strings
1349−-- and return it, along with the suffixes of each string at which they
1350−-- no longer match.
1351−--
1352−-- If the strings do not have a common prefix or either one is empty,
1353−-- this function returns 'Nothing'.
1354−--
1355−-- Examples:
1356−--
1357−-- > commonPrefixes "foobar" "fooquux" == Just ("foo","bar","quux")
1358−-- > commonPrefixes "veeble" "fetzer" == Nothing
1359−-- > commonPrefixes "" "baz" == Nothing
1360−commonPrefixes :: JSString -> JSString -> Maybe (JSString,JSString,JSString)
1361−commonPrefixes = coerce T.commonPrefixes
1362−{-# INLINE commonPrefixes #-}
1363−
1364−-- | /O(n)/ Return the prefix of the second string if its suffix
1365−-- matches the entire first string.
1366−--
1367−-- Examples:
1368−--
1369−-- > stripSuffix "bar" "foobar" == Just "foo"
1370−-- > stripSuffix "" "baz" == Just "baz"
1371−-- > stripSuffix "foo" "quux" == Nothing
1372−--
1373−-- This is particularly useful with the @ViewPatterns@ extension to
1374−-- GHC, as follows:
1375−--
1376−-- > {-# LANGUAGE ViewPatterns #-}
1377−-- > import Data.Text as T
1378−-- >
1379−-- > quuxLength :: Text -> Int
1380−-- > quuxLength (stripSuffix "quux" -> Just pre) = T.length pre
1381−-- > quuxLength _ = -1
1382−stripSuffix :: JSString -> JSString -> Maybe JSString
1383−stripSuffix = coerce T.stripSuffix
1384−{-# INLINE stripSuffix #-}
1385−
1386−---- | Add a list of non-negative numbers. Errors out on overflow.
1387−--sumP :: String -> [Int] -> Int
1388−--sumP fun = go 0
1389−-- where go !a (x:xs)
1390−-- | ax >= 0 = go ax xs
1391−-- | otherwise = overflowError fun
1392−-- where ax = a + x
1393−-- go a _ = a
1394−--
1395−--emptyError :: String -> a
1396−--emptyError fun = P.error $ "Data.JSString." ++ fun ++ ": empty input"
1397−--
1398−--overflowError :: String -> a
1399−--overflowError fun = P.error $ "Data.JSString." ++ fun ++ ": size overflow"
1400−--
1401−--charWidth :: Int# -> Int#
1402−--charWidth cp | isTrue# (cp >=# 0x10000#) = 2#
1403−-- | otherwise = 1#
1404−--{-# INLINE charWidth #-}