Commits

Bryan O'Sullivan committed d73fadd

Rename strict fusion-related modules

Comments (0)

Files changed (22)

 import qualified Data.List as L
 import Data.Monoid (Monoid(..))
 import Data.String (IsString(..))
-import qualified Data.Text.Fusion as S
-import qualified Data.Text.Fusion.Common as S
-import Data.Text.Fusion (stream, reverseStream, unstream)
+import qualified Data.Text.Internal.Fusion as S
+import qualified Data.Text.Internal.Fusion.Common as S
+import Data.Text.Internal.Fusion (stream, reverseStream, unstream)
 import Data.Text.Private (span_)
 import Data.Text.Internal (Text(..), empty, firstf, safe, text, textP)
 import qualified Prelude as P

Data/Text/Encoding.hs

 import qualified Data.Text.Array as A
 import qualified Data.Text.Internal.Encoding.Fusion as E
 import qualified Data.Text.Internal.Encoding.Utf16 as U16
-import qualified Data.Text.Fusion as F
+import qualified Data.Text.Internal.Fusion as F
 import Data.Text.Unsafe (unsafeDupablePerformIO)
 
 #include "text_cbits.h"

Data/Text/Fusion.hs

-{-# LANGUAGE BangPatterns, MagicHash #-}
-
--- |
--- Module      : Data.Text.Fusion
--- Copyright   : (c) Tom Harper 2008-2009,
---               (c) Bryan O'Sullivan 2009-2010,
---               (c) Duncan Coutts 2009
---
--- License     : BSD-style
--- Maintainer  : bos@serpentine.com, rtomharper@googlemail.com,
---               duncan@haskell.org
--- Stability   : experimental
--- Portability : GHC
---
--- Text manipulation functions represented as fusible operations over
--- streams.
-module Data.Text.Fusion
-    (
-    -- * Types
-      Stream(..)
-    , Step(..)
-
-    -- * Creation and elimination
-    , stream
-    , unstream
-    , reverseStream
-
-    , length
-
-    -- * Transformations
-    , reverse
-
-    -- * Construction
-    -- ** Scans
-    , reverseScanr
-
-    -- ** Accumulating maps
-    , mapAccumL
-
-    -- ** Generation and unfolding
-    , unfoldrN
-
-    -- * Indexing
-    , index
-    , findIndex
-    , countChar
-    ) where
-
-import Prelude (Bool(..), Char, Maybe(..), Monad(..), Int,
-                Num(..), Ord(..), ($), (&&),
-                fromIntegral, otherwise)
-import Data.Bits ((.&.))
-import Data.Text.Internal (Text(..))
-import Data.Text.Private (runText)
-import Data.Text.UnsafeChar (ord, unsafeChr, unsafeWrite)
-import Data.Text.UnsafeShift (shiftL, shiftR)
-import qualified Data.Text.Array as A
-import qualified Data.Text.Fusion.Common as S
-import Data.Text.Fusion.Internal
-import Data.Text.Fusion.Size
-import qualified Data.Text.Internal as I
-import qualified Data.Text.Internal.Encoding.Utf16 as U16
-
-default(Int)
-
--- | /O(n)/ Convert a 'Text' into a 'Stream Char'.
-stream :: Text -> Stream Char
-stream (Text arr off len) = Stream next off (maxSize len)
-    where
-      !end = off+len
-      next !i
-          | i >= end                   = Done
-          | n >= 0xD800 && n <= 0xDBFF = Yield (U16.chr2 n n2) (i + 2)
-          | otherwise                  = Yield (unsafeChr n) (i + 1)
-          where
-            n  = A.unsafeIndex arr i
-            n2 = A.unsafeIndex arr (i + 1)
-{-# INLINE [0] stream #-}
-
--- | /O(n)/ Convert a 'Text' into a 'Stream Char', but iterate
--- backwards.
-reverseStream :: Text -> Stream Char
-reverseStream (Text arr off len) = Stream next (off+len-1) (maxSize len)
-    where
-      {-# INLINE next #-}
-      next !i
-          | i < off                    = Done
-          | n >= 0xDC00 && n <= 0xDFFF = Yield (U16.chr2 n2 n) (i - 2)
-          | otherwise                  = Yield (unsafeChr n) (i - 1)
-          where
-            n  = A.unsafeIndex arr i
-            n2 = A.unsafeIndex arr (i - 1)
-{-# INLINE [0] reverseStream #-}
-
--- | /O(n)/ Convert a 'Stream Char' into a 'Text'.
-unstream :: Stream Char -> Text
-unstream (Stream next0 s0 len) = runText $ \done -> do
-  let mlen = upperBound 4 len
-  arr0 <- A.new mlen
-  let outer arr top = loop
-       where
-        loop !s !i =
-            case next0 s of
-              Done          -> done arr i
-              Skip s'       -> loop s' i
-              Yield x s'
-                | j >= top  -> {-# SCC "unstream/resize" #-} do
-                               let top' = (top + 1) `shiftL` 1
-                               arr' <- A.new top'
-                               A.copyM arr' 0 arr 0 top
-                               outer arr' top' s i
-                | otherwise -> do d <- unsafeWrite arr i x
-                                  loop s' (i+d)
-                where j | ord x < 0x10000 = i
-                        | otherwise       = i + 1
-  outer arr0 mlen s0 0
-{-# INLINE [0] unstream #-}
-{-# RULES "STREAM stream/unstream fusion" forall s. stream (unstream s) = s #-}
-
-
--- ----------------------------------------------------------------------------
--- * Basic stream functions
-
-length :: Stream Char -> Int
-length = S.lengthI
-{-# INLINE[0] length #-}
-
--- | /O(n)/ Reverse the characters of a string.
-reverse :: Stream Char -> Text
-reverse (Stream next s len0)
-    | isEmpty len0 = I.empty
-    | otherwise    = I.textP arr off' len'
-  where
-    len0' = upperBound 4 (larger len0 4)
-    (arr, (off', len')) = A.run2 (A.new len0' >>= loop s (len0'-1) len0')
-    loop !s0 !i !len marr =
-        case next s0 of
-          Done -> return (marr, (j, len-j))
-              where j = i + 1
-          Skip s1    -> loop s1 i len marr
-          Yield x s1 | i < least -> {-# SCC "reverse/resize" #-} do
-                       let newLen = len `shiftL` 1
-                       marr' <- A.new newLen
-                       A.copyM marr' (newLen-len) marr 0 len
-                       write s1 (len+i) newLen marr'
-                     | otherwise -> write s1 i len marr
-            where n = ord x
-                  least | n < 0x10000 = 0
-                        | otherwise   = 1
-                  m = n - 0x10000
-                  lo = fromIntegral $ (m `shiftR` 10) + 0xD800
-                  hi = fromIntegral $ (m .&. 0x3FF) + 0xDC00
-                  write t j l mar
-                      | n < 0x10000 = do
-                          A.unsafeWrite mar j (fromIntegral n)
-                          loop t (j-1) l mar
-                      | otherwise = do
-                          A.unsafeWrite mar (j-1) lo
-                          A.unsafeWrite mar j hi
-                          loop t (j-2) l mar
-{-# INLINE [0] reverse #-}
-
--- | /O(n)/ Perform the equivalent of 'scanr' over a list, only with
--- the input and result reversed.
-reverseScanr :: (Char -> Char -> Char) -> Char -> Stream Char -> Stream Char
-reverseScanr f z0 (Stream next0 s0 len) = Stream next (S1 :*: z0 :*: s0) (len+1) -- HINT maybe too low
-  where
-    {-# INLINE next #-}
-    next (S1 :*: z :*: s) = Yield z (S2 :*: z :*: s)
-    next (S2 :*: z :*: s) = case next0 s of
-                              Yield x s' -> let !x' = f x z
-                                            in Yield x' (S2 :*: x' :*: s')
-                              Skip s'    -> Skip (S2 :*: z :*: s')
-                              Done       -> Done
-{-# INLINE reverseScanr #-}
-
--- | /O(n)/ Like 'unfoldr', 'unfoldrN' builds a stream from a seed
--- value. However, the length of the result is limited by the
--- first argument to 'unfoldrN'. This function is more efficient than
--- 'unfoldr' when the length of the result is known.
-unfoldrN :: Int -> (a -> Maybe (Char,a)) -> a -> Stream Char
-unfoldrN n = S.unfoldrNI n
-{-# INLINE [0] unfoldrN #-}
-
--------------------------------------------------------------------------------
--- ** Indexing streams
-
--- | /O(n)/ stream index (subscript) operator, starting from 0.
-index :: Stream Char -> Int -> Char
-index = S.indexI
-{-# INLINE [0] index #-}
-
--- | The 'findIndex' function takes a predicate and a stream and
--- returns the index of the first element in the stream
--- satisfying the predicate.
-findIndex :: (Char -> Bool) -> Stream Char -> Maybe Int
-findIndex = S.findIndexI
-{-# INLINE [0] findIndex #-}
-
--- | /O(n)/ The 'count' function returns the number of times the query
--- element appears in the given stream.
-countChar :: Char -> Stream Char -> Int
-countChar = S.countCharI
-{-# INLINE [0] countChar #-}
-
--- | /O(n)/ Like a combination of 'map' and 'foldl''. Applies a
--- function to each element of a 'Text', passing an accumulating
--- parameter from left to right, and returns a final 'Text'.
-mapAccumL :: (a -> Char -> (a,Char)) -> a -> Stream Char -> (a, Text)
-mapAccumL f z0 (Stream next0 s0 len) = (nz,I.textP na 0 nl)
-  where
-    (na,(nz,nl)) = A.run2 (A.new mlen >>= \arr -> outer arr mlen z0 s0 0)
-      where mlen = upperBound 4 len
-    outer arr top = loop
-      where
-        loop !z !s !i =
-            case next0 s of
-              Done          -> return (arr, (z,i))
-              Skip s'       -> loop z s' i
-              Yield x s'
-                | j >= top  -> {-# SCC "mapAccumL/resize" #-} do
-                               let top' = (top + 1) `shiftL` 1
-                               arr' <- A.new top'
-                               A.copyM arr' 0 arr 0 top
-                               outer arr' top' z s i
-                | otherwise -> do d <- unsafeWrite arr i c
-                                  loop z' s' (i+d)
-                where (z',c) = f z x
-                      j | ord c < 0x10000 = i
-                        | otherwise       = i + 1
-{-# INLINE [0] mapAccumL #-}

Data/Text/Fusion/CaseMapping.hs

-{-# LANGUAGE Rank2Types #-}
--- AUTOMATICALLY GENERATED - DO NOT EDIT
--- Generated by scripts/SpecialCasing.hs
--- CaseFolding-6.3.0.txt
--- Date: 2012-12-20, 22:14:35 GMT [MD]
--- SpecialCasing-6.3.0.txt
--- Date: 2013-05-08, 13:54:51 GMT [MD]
-
-module Data.Text.Fusion.CaseMapping where
-import Data.Char
-import Data.Text.Fusion.Internal
-
-upperMapping :: forall s. Char -> s -> Step (CC s) Char
-{-# INLINE upperMapping #-}
--- LATIN SMALL LETTER SHARP S
-upperMapping '\x00df' s = Yield '\x0053' (CC s '\x0053' '\x0000')
--- LATIN SMALL LIGATURE FF
-upperMapping '\xfb00' s = Yield '\x0046' (CC s '\x0046' '\x0000')
--- LATIN SMALL LIGATURE FI
-upperMapping '\xfb01' s = Yield '\x0046' (CC s '\x0049' '\x0000')
--- LATIN SMALL LIGATURE FL
-upperMapping '\xfb02' s = Yield '\x0046' (CC s '\x004c' '\x0000')
--- LATIN SMALL LIGATURE FFI
-upperMapping '\xfb03' s = Yield '\x0046' (CC s '\x0046' '\x0049')
--- LATIN SMALL LIGATURE FFL
-upperMapping '\xfb04' s = Yield '\x0046' (CC s '\x0046' '\x004c')
--- LATIN SMALL LIGATURE LONG S T
-upperMapping '\xfb05' s = Yield '\x0053' (CC s '\x0054' '\x0000')
--- LATIN SMALL LIGATURE ST
-upperMapping '\xfb06' s = Yield '\x0053' (CC s '\x0054' '\x0000')
--- ARMENIAN SMALL LIGATURE ECH YIWN
-upperMapping '\x0587' s = Yield '\x0535' (CC s '\x0552' '\x0000')
--- ARMENIAN SMALL LIGATURE MEN NOW
-upperMapping '\xfb13' s = Yield '\x0544' (CC s '\x0546' '\x0000')
--- ARMENIAN SMALL LIGATURE MEN ECH
-upperMapping '\xfb14' s = Yield '\x0544' (CC s '\x0535' '\x0000')
--- ARMENIAN SMALL LIGATURE MEN INI
-upperMapping '\xfb15' s = Yield '\x0544' (CC s '\x053b' '\x0000')
--- ARMENIAN SMALL LIGATURE VEW NOW
-upperMapping '\xfb16' s = Yield '\x054e' (CC s '\x0546' '\x0000')
--- ARMENIAN SMALL LIGATURE MEN XEH
-upperMapping '\xfb17' s = Yield '\x0544' (CC s '\x053d' '\x0000')
--- LATIN SMALL LETTER N PRECEDED BY APOSTROPHE
-upperMapping '\x0149' s = Yield '\x02bc' (CC s '\x004e' '\x0000')
--- GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
-upperMapping '\x0390' s = Yield '\x0399' (CC s '\x0308' '\x0301')
--- GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
-upperMapping '\x03b0' s = Yield '\x03a5' (CC s '\x0308' '\x0301')
--- LATIN SMALL LETTER J WITH CARON
-upperMapping '\x01f0' s = Yield '\x004a' (CC s '\x030c' '\x0000')
--- LATIN SMALL LETTER H WITH LINE BELOW
-upperMapping '\x1e96' s = Yield '\x0048' (CC s '\x0331' '\x0000')
--- LATIN SMALL LETTER T WITH DIAERESIS
-upperMapping '\x1e97' s = Yield '\x0054' (CC s '\x0308' '\x0000')
--- LATIN SMALL LETTER W WITH RING ABOVE
-upperMapping '\x1e98' s = Yield '\x0057' (CC s '\x030a' '\x0000')
--- LATIN SMALL LETTER Y WITH RING ABOVE
-upperMapping '\x1e99' s = Yield '\x0059' (CC s '\x030a' '\x0000')
--- LATIN SMALL LETTER A WITH RIGHT HALF RING
-upperMapping '\x1e9a' s = Yield '\x0041' (CC s '\x02be' '\x0000')
--- GREEK SMALL LETTER UPSILON WITH PSILI
-upperMapping '\x1f50' s = Yield '\x03a5' (CC s '\x0313' '\x0000')
--- GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA
-upperMapping '\x1f52' s = Yield '\x03a5' (CC s '\x0313' '\x0300')
--- GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA
-upperMapping '\x1f54' s = Yield '\x03a5' (CC s '\x0313' '\x0301')
--- GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI
-upperMapping '\x1f56' s = Yield '\x03a5' (CC s '\x0313' '\x0342')
--- GREEK SMALL LETTER ALPHA WITH PERISPOMENI
-upperMapping '\x1fb6' s = Yield '\x0391' (CC s '\x0342' '\x0000')
--- GREEK SMALL LETTER ETA WITH PERISPOMENI
-upperMapping '\x1fc6' s = Yield '\x0397' (CC s '\x0342' '\x0000')
--- GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA
-upperMapping '\x1fd2' s = Yield '\x0399' (CC s '\x0308' '\x0300')
--- GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA
-upperMapping '\x1fd3' s = Yield '\x0399' (CC s '\x0308' '\x0301')
--- GREEK SMALL LETTER IOTA WITH PERISPOMENI
-upperMapping '\x1fd6' s = Yield '\x0399' (CC s '\x0342' '\x0000')
--- GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI
-upperMapping '\x1fd7' s = Yield '\x0399' (CC s '\x0308' '\x0342')
--- GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA
-upperMapping '\x1fe2' s = Yield '\x03a5' (CC s '\x0308' '\x0300')
--- GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA
-upperMapping '\x1fe3' s = Yield '\x03a5' (CC s '\x0308' '\x0301')
--- GREEK SMALL LETTER RHO WITH PSILI
-upperMapping '\x1fe4' s = Yield '\x03a1' (CC s '\x0313' '\x0000')
--- GREEK SMALL LETTER UPSILON WITH PERISPOMENI
-upperMapping '\x1fe6' s = Yield '\x03a5' (CC s '\x0342' '\x0000')
--- GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI
-upperMapping '\x1fe7' s = Yield '\x03a5' (CC s '\x0308' '\x0342')
--- GREEK SMALL LETTER OMEGA WITH PERISPOMENI
-upperMapping '\x1ff6' s = Yield '\x03a9' (CC s '\x0342' '\x0000')
--- GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI
-upperMapping '\x1f80' s = Yield '\x1f08' (CC s '\x0399' '\x0000')
--- GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI
-upperMapping '\x1f81' s = Yield '\x1f09' (CC s '\x0399' '\x0000')
--- GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI
-upperMapping '\x1f82' s = Yield '\x1f0a' (CC s '\x0399' '\x0000')
--- GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI
-upperMapping '\x1f83' s = Yield '\x1f0b' (CC s '\x0399' '\x0000')
--- GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI
-upperMapping '\x1f84' s = Yield '\x1f0c' (CC s '\x0399' '\x0000')
--- GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI
-upperMapping '\x1f85' s = Yield '\x1f0d' (CC s '\x0399' '\x0000')
--- GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
-upperMapping '\x1f86' s = Yield '\x1f0e' (CC s '\x0399' '\x0000')
--- GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
-upperMapping '\x1f87' s = Yield '\x1f0f' (CC s '\x0399' '\x0000')
--- GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI
-upperMapping '\x1f88' s = Yield '\x1f08' (CC s '\x0399' '\x0000')
--- GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI
-upperMapping '\x1f89' s = Yield '\x1f09' (CC s '\x0399' '\x0000')
--- GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI
-upperMapping '\x1f8a' s = Yield '\x1f0a' (CC s '\x0399' '\x0000')
--- GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI
-upperMapping '\x1f8b' s = Yield '\x1f0b' (CC s '\x0399' '\x0000')
--- GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI
-upperMapping '\x1f8c' s = Yield '\x1f0c' (CC s '\x0399' '\x0000')
--- GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI
-upperMapping '\x1f8d' s = Yield '\x1f0d' (CC s '\x0399' '\x0000')
--- GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
-upperMapping '\x1f8e' s = Yield '\x1f0e' (CC s '\x0399' '\x0000')
--- GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
-upperMapping '\x1f8f' s = Yield '\x1f0f' (CC s '\x0399' '\x0000')
--- GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI
-upperMapping '\x1f90' s = Yield '\x1f28' (CC s '\x0399' '\x0000')
--- GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI
-upperMapping '\x1f91' s = Yield '\x1f29' (CC s '\x0399' '\x0000')
--- GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI
-upperMapping '\x1f92' s = Yield '\x1f2a' (CC s '\x0399' '\x0000')
--- GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI
-upperMapping '\x1f93' s = Yield '\x1f2b' (CC s '\x0399' '\x0000')
--- GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI
-upperMapping '\x1f94' s = Yield '\x1f2c' (CC s '\x0399' '\x0000')
--- GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI
-upperMapping '\x1f95' s = Yield '\x1f2d' (CC s '\x0399' '\x0000')
--- GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
-upperMapping '\x1f96' s = Yield '\x1f2e' (CC s '\x0399' '\x0000')
--- GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
-upperMapping '\x1f97' s = Yield '\x1f2f' (CC s '\x0399' '\x0000')
--- GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI
-upperMapping '\x1f98' s = Yield '\x1f28' (CC s '\x0399' '\x0000')
--- GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI
-upperMapping '\x1f99' s = Yield '\x1f29' (CC s '\x0399' '\x0000')
--- GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI
-upperMapping '\x1f9a' s = Yield '\x1f2a' (CC s '\x0399' '\x0000')
--- GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI
-upperMapping '\x1f9b' s = Yield '\x1f2b' (CC s '\x0399' '\x0000')
--- GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI
-upperMapping '\x1f9c' s = Yield '\x1f2c' (CC s '\x0399' '\x0000')
--- GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI
-upperMapping '\x1f9d' s = Yield '\x1f2d' (CC s '\x0399' '\x0000')
--- GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
-upperMapping '\x1f9e' s = Yield '\x1f2e' (CC s '\x0399' '\x0000')
--- GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
-upperMapping '\x1f9f' s = Yield '\x1f2f' (CC s '\x0399' '\x0000')
--- GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI
-upperMapping '\x1fa0' s = Yield '\x1f68' (CC s '\x0399' '\x0000')
--- GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI
-upperMapping '\x1fa1' s = Yield '\x1f69' (CC s '\x0399' '\x0000')
--- GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI
-upperMapping '\x1fa2' s = Yield '\x1f6a' (CC s '\x0399' '\x0000')
--- GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI
-upperMapping '\x1fa3' s = Yield '\x1f6b' (CC s '\x0399' '\x0000')
--- GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI
-upperMapping '\x1fa4' s = Yield '\x1f6c' (CC s '\x0399' '\x0000')
--- GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI
-upperMapping '\x1fa5' s = Yield '\x1f6d' (CC s '\x0399' '\x0000')
--- GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
-upperMapping '\x1fa6' s = Yield '\x1f6e' (CC s '\x0399' '\x0000')
--- GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
-upperMapping '\x1fa7' s = Yield '\x1f6f' (CC s '\x0399' '\x0000')
--- GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI
-upperMapping '\x1fa8' s = Yield '\x1f68' (CC s '\x0399' '\x0000')
--- GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI
-upperMapping '\x1fa9' s = Yield '\x1f69' (CC s '\x0399' '\x0000')
--- GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI
-upperMapping '\x1faa' s = Yield '\x1f6a' (CC s '\x0399' '\x0000')
--- GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI
-upperMapping '\x1fab' s = Yield '\x1f6b' (CC s '\x0399' '\x0000')
--- GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI
-upperMapping '\x1fac' s = Yield '\x1f6c' (CC s '\x0399' '\x0000')
--- GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI
-upperMapping '\x1fad' s = Yield '\x1f6d' (CC s '\x0399' '\x0000')
--- GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
-upperMapping '\x1fae' s = Yield '\x1f6e' (CC s '\x0399' '\x0000')
--- GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
-upperMapping '\x1faf' s = Yield '\x1f6f' (CC s '\x0399' '\x0000')
--- GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI
-upperMapping '\x1fb3' s = Yield '\x0391' (CC s '\x0399' '\x0000')
--- GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI
-upperMapping '\x1fbc' s = Yield '\x0391' (CC s '\x0399' '\x0000')
--- GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI
-upperMapping '\x1fc3' s = Yield '\x0397' (CC s '\x0399' '\x0000')
--- GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI
-upperMapping '\x1fcc' s = Yield '\x0397' (CC s '\x0399' '\x0000')
--- GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI
-upperMapping '\x1ff3' s = Yield '\x03a9' (CC s '\x0399' '\x0000')
--- GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI
-upperMapping '\x1ffc' s = Yield '\x03a9' (CC s '\x0399' '\x0000')
--- GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI
-upperMapping '\x1fb2' s = Yield '\x1fba' (CC s '\x0399' '\x0000')
--- GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI
-upperMapping '\x1fb4' s = Yield '\x0386' (CC s '\x0399' '\x0000')
--- GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI
-upperMapping '\x1fc2' s = Yield '\x1fca' (CC s '\x0399' '\x0000')
--- GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI
-upperMapping '\x1fc4' s = Yield '\x0389' (CC s '\x0399' '\x0000')
--- GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI
-upperMapping '\x1ff2' s = Yield '\x1ffa' (CC s '\x0399' '\x0000')
--- GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI
-upperMapping '\x1ff4' s = Yield '\x038f' (CC s '\x0399' '\x0000')
--- GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI
-upperMapping '\x1fb7' s = Yield '\x0391' (CC s '\x0342' '\x0399')
--- GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI
-upperMapping '\x1fc7' s = Yield '\x0397' (CC s '\x0342' '\x0399')
--- GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI
-upperMapping '\x1ff7' s = Yield '\x03a9' (CC s '\x0342' '\x0399')
-upperMapping c s = Yield (toUpper c) (CC s '\0' '\0')
-lowerMapping :: forall s. Char -> s -> Step (CC s) Char
-{-# INLINE lowerMapping #-}
--- LATIN CAPITAL LETTER I WITH DOT ABOVE
-lowerMapping '\x0130' s = Yield '\x0069' (CC s '\x0307' '\x0000')
-lowerMapping c s = Yield (toLower c) (CC s '\0' '\0')
-titleMapping :: forall s. Char -> s -> Step (CC s) Char
-{-# INLINE titleMapping #-}
--- LATIN SMALL LETTER SHARP S
-titleMapping '\x00df' s = Yield '\x0053' (CC s '\x0073' '\x0000')
--- LATIN SMALL LIGATURE FF
-titleMapping '\xfb00' s = Yield '\x0046' (CC s '\x0066' '\x0000')
--- LATIN SMALL LIGATURE FI
-titleMapping '\xfb01' s = Yield '\x0046' (CC s '\x0069' '\x0000')
--- LATIN SMALL LIGATURE FL
-titleMapping '\xfb02' s = Yield '\x0046' (CC s '\x006c' '\x0000')
--- LATIN SMALL LIGATURE FFI
-titleMapping '\xfb03' s = Yield '\x0046' (CC s '\x0066' '\x0069')
--- LATIN SMALL LIGATURE FFL
-titleMapping '\xfb04' s = Yield '\x0046' (CC s '\x0066' '\x006c')
--- LATIN SMALL LIGATURE LONG S T
-titleMapping '\xfb05' s = Yield '\x0053' (CC s '\x0074' '\x0000')
--- LATIN SMALL LIGATURE ST
-titleMapping '\xfb06' s = Yield '\x0053' (CC s '\x0074' '\x0000')
--- ARMENIAN SMALL LIGATURE ECH YIWN
-titleMapping '\x0587' s = Yield '\x0535' (CC s '\x0582' '\x0000')
--- ARMENIAN SMALL LIGATURE MEN NOW
-titleMapping '\xfb13' s = Yield '\x0544' (CC s '\x0576' '\x0000')
--- ARMENIAN SMALL LIGATURE MEN ECH
-titleMapping '\xfb14' s = Yield '\x0544' (CC s '\x0565' '\x0000')
--- ARMENIAN SMALL LIGATURE MEN INI
-titleMapping '\xfb15' s = Yield '\x0544' (CC s '\x056b' '\x0000')
--- ARMENIAN SMALL LIGATURE VEW NOW
-titleMapping '\xfb16' s = Yield '\x054e' (CC s '\x0576' '\x0000')
--- ARMENIAN SMALL LIGATURE MEN XEH
-titleMapping '\xfb17' s = Yield '\x0544' (CC s '\x056d' '\x0000')
--- LATIN SMALL LETTER N PRECEDED BY APOSTROPHE
-titleMapping '\x0149' s = Yield '\x02bc' (CC s '\x004e' '\x0000')
--- GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
-titleMapping '\x0390' s = Yield '\x0399' (CC s '\x0308' '\x0301')
--- GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
-titleMapping '\x03b0' s = Yield '\x03a5' (CC s '\x0308' '\x0301')
--- LATIN SMALL LETTER J WITH CARON
-titleMapping '\x01f0' s = Yield '\x004a' (CC s '\x030c' '\x0000')
--- LATIN SMALL LETTER H WITH LINE BELOW
-titleMapping '\x1e96' s = Yield '\x0048' (CC s '\x0331' '\x0000')
--- LATIN SMALL LETTER T WITH DIAERESIS
-titleMapping '\x1e97' s = Yield '\x0054' (CC s '\x0308' '\x0000')
--- LATIN SMALL LETTER W WITH RING ABOVE
-titleMapping '\x1e98' s = Yield '\x0057' (CC s '\x030a' '\x0000')
--- LATIN SMALL LETTER Y WITH RING ABOVE
-titleMapping '\x1e99' s = Yield '\x0059' (CC s '\x030a' '\x0000')
--- LATIN SMALL LETTER A WITH RIGHT HALF RING
-titleMapping '\x1e9a' s = Yield '\x0041' (CC s '\x02be' '\x0000')
--- GREEK SMALL LETTER UPSILON WITH PSILI
-titleMapping '\x1f50' s = Yield '\x03a5' (CC s '\x0313' '\x0000')
--- GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA
-titleMapping '\x1f52' s = Yield '\x03a5' (CC s '\x0313' '\x0300')
--- GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA
-titleMapping '\x1f54' s = Yield '\x03a5' (CC s '\x0313' '\x0301')
--- GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI
-titleMapping '\x1f56' s = Yield '\x03a5' (CC s '\x0313' '\x0342')
--- GREEK SMALL LETTER ALPHA WITH PERISPOMENI
-titleMapping '\x1fb6' s = Yield '\x0391' (CC s '\x0342' '\x0000')
--- GREEK SMALL LETTER ETA WITH PERISPOMENI
-titleMapping '\x1fc6' s = Yield '\x0397' (CC s '\x0342' '\x0000')
--- GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA
-titleMapping '\x1fd2' s = Yield '\x0399' (CC s '\x0308' '\x0300')
--- GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA
-titleMapping '\x1fd3' s = Yield '\x0399' (CC s '\x0308' '\x0301')
--- GREEK SMALL LETTER IOTA WITH PERISPOMENI
-titleMapping '\x1fd6' s = Yield '\x0399' (CC s '\x0342' '\x0000')
--- GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI
-titleMapping '\x1fd7' s = Yield '\x0399' (CC s '\x0308' '\x0342')
--- GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA
-titleMapping '\x1fe2' s = Yield '\x03a5' (CC s '\x0308' '\x0300')
--- GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA
-titleMapping '\x1fe3' s = Yield '\x03a5' (CC s '\x0308' '\x0301')
--- GREEK SMALL LETTER RHO WITH PSILI
-titleMapping '\x1fe4' s = Yield '\x03a1' (CC s '\x0313' '\x0000')
--- GREEK SMALL LETTER UPSILON WITH PERISPOMENI
-titleMapping '\x1fe6' s = Yield '\x03a5' (CC s '\x0342' '\x0000')
--- GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI
-titleMapping '\x1fe7' s = Yield '\x03a5' (CC s '\x0308' '\x0342')
--- GREEK SMALL LETTER OMEGA WITH PERISPOMENI
-titleMapping '\x1ff6' s = Yield '\x03a9' (CC s '\x0342' '\x0000')
--- GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI
-titleMapping '\x1fb2' s = Yield '\x1fba' (CC s '\x0345' '\x0000')
--- GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI
-titleMapping '\x1fb4' s = Yield '\x0386' (CC s '\x0345' '\x0000')
--- GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI
-titleMapping '\x1fc2' s = Yield '\x1fca' (CC s '\x0345' '\x0000')
--- GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI
-titleMapping '\x1fc4' s = Yield '\x0389' (CC s '\x0345' '\x0000')
--- GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI
-titleMapping '\x1ff2' s = Yield '\x1ffa' (CC s '\x0345' '\x0000')
--- GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI
-titleMapping '\x1ff4' s = Yield '\x038f' (CC s '\x0345' '\x0000')
--- GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI
-titleMapping '\x1fb7' s = Yield '\x0391' (CC s '\x0342' '\x0345')
--- GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI
-titleMapping '\x1fc7' s = Yield '\x0397' (CC s '\x0342' '\x0345')
--- GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI
-titleMapping '\x1ff7' s = Yield '\x03a9' (CC s '\x0342' '\x0345')
-titleMapping c s = Yield (toTitle c) (CC s '\0' '\0')
-foldMapping :: forall s. Char -> s -> Step (CC s) Char
-{-# INLINE foldMapping #-}
--- MICRO SIGN
-foldMapping '\x00b5' s = Yield '\x03bc' (CC s '\x0000' '\x0000')
--- LATIN SMALL LETTER SHARP S
-foldMapping '\x00df' s = Yield '\x0073' (CC s '\x0073' '\x0000')
--- LATIN CAPITAL LETTER I WITH DOT ABOVE
-foldMapping '\x0130' s = Yield '\x0069' (CC s '\x0307' '\x0000')
--- LATIN SMALL LETTER N PRECEDED BY APOSTROPHE
-foldMapping '\x0149' s = Yield '\x02bc' (CC s '\x006e' '\x0000')
--- LATIN SMALL LETTER LONG S
-foldMapping '\x017f' s = Yield '\x0073' (CC s '\x0000' '\x0000')
--- LATIN SMALL LETTER J WITH CARON
-foldMapping '\x01f0' s = Yield '\x006a' (CC s '\x030c' '\x0000')
--- COMBINING GREEK YPOGEGRAMMENI
-foldMapping '\x0345' s = Yield '\x03b9' (CC s '\x0000' '\x0000')
--- GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
-foldMapping '\x0390' s = Yield '\x03b9' (CC s '\x0308' '\x0301')
--- GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
-foldMapping '\x03b0' s = Yield '\x03c5' (CC s '\x0308' '\x0301')
--- GREEK SMALL LETTER FINAL SIGMA
-foldMapping '\x03c2' s = Yield '\x03c3' (CC s '\x0000' '\x0000')
--- GREEK BETA SYMBOL
-foldMapping '\x03d0' s = Yield '\x03b2' (CC s '\x0000' '\x0000')
--- GREEK THETA SYMBOL
-foldMapping '\x03d1' s = Yield '\x03b8' (CC s '\x0000' '\x0000')
--- GREEK PHI SYMBOL
-foldMapping '\x03d5' s = Yield '\x03c6' (CC s '\x0000' '\x0000')
--- GREEK PI SYMBOL
-foldMapping '\x03d6' s = Yield '\x03c0' (CC s '\x0000' '\x0000')
--- GREEK KAPPA SYMBOL
-foldMapping '\x03f0' s = Yield '\x03ba' (CC s '\x0000' '\x0000')
--- GREEK RHO SYMBOL
-foldMapping '\x03f1' s = Yield '\x03c1' (CC s '\x0000' '\x0000')
--- GREEK LUNATE EPSILON SYMBOL
-foldMapping '\x03f5' s = Yield '\x03b5' (CC s '\x0000' '\x0000')
--- ARMENIAN SMALL LIGATURE ECH YIWN
-foldMapping '\x0587' s = Yield '\x0565' (CC s '\x0582' '\x0000')
--- GEORGIAN CAPITAL LETTER YN
-foldMapping '\x10c7' s = Yield '\x2d27' (CC s '\x0000' '\x0000')
--- GEORGIAN CAPITAL LETTER AEN
-foldMapping '\x10cd' s = Yield '\x2d2d' (CC s '\x0000' '\x0000')
--- LATIN SMALL LETTER H WITH LINE BELOW
-foldMapping '\x1e96' s = Yield '\x0068' (CC s '\x0331' '\x0000')
--- LATIN SMALL LETTER T WITH DIAERESIS
-foldMapping '\x1e97' s = Yield '\x0074' (CC s '\x0308' '\x0000')
--- LATIN SMALL LETTER W WITH RING ABOVE
-foldMapping '\x1e98' s = Yield '\x0077' (CC s '\x030a' '\x0000')
--- LATIN SMALL LETTER Y WITH RING ABOVE
-foldMapping '\x1e99' s = Yield '\x0079' (CC s '\x030a' '\x0000')
--- LATIN SMALL LETTER A WITH RIGHT HALF RING
-foldMapping '\x1e9a' s = Yield '\x0061' (CC s '\x02be' '\x0000')
--- LATIN SMALL LETTER LONG S WITH DOT ABOVE
-foldMapping '\x1e9b' s = Yield '\x1e61' (CC s '\x0000' '\x0000')
--- LATIN CAPITAL LETTER SHARP S
-foldMapping '\x1e9e' s = Yield '\x0073' (CC s '\x0073' '\x0000')
--- GREEK SMALL LETTER UPSILON WITH PSILI
-foldMapping '\x1f50' s = Yield '\x03c5' (CC s '\x0313' '\x0000')
--- GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA
-foldMapping '\x1f52' s = Yield '\x03c5' (CC s '\x0313' '\x0300')
--- GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA
-foldMapping '\x1f54' s = Yield '\x03c5' (CC s '\x0313' '\x0301')
--- GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI
-foldMapping '\x1f56' s = Yield '\x03c5' (CC s '\x0313' '\x0342')
--- GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI
-foldMapping '\x1f80' s = Yield '\x1f00' (CC s '\x03b9' '\x0000')
--- GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI
-foldMapping '\x1f81' s = Yield '\x1f01' (CC s '\x03b9' '\x0000')
--- GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI
-foldMapping '\x1f82' s = Yield '\x1f02' (CC s '\x03b9' '\x0000')
--- GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI
-foldMapping '\x1f83' s = Yield '\x1f03' (CC s '\x03b9' '\x0000')
--- GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI
-foldMapping '\x1f84' s = Yield '\x1f04' (CC s '\x03b9' '\x0000')
--- GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI
-foldMapping '\x1f85' s = Yield '\x1f05' (CC s '\x03b9' '\x0000')
--- GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
-foldMapping '\x1f86' s = Yield '\x1f06' (CC s '\x03b9' '\x0000')
--- GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
-foldMapping '\x1f87' s = Yield '\x1f07' (CC s '\x03b9' '\x0000')
--- GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI
-foldMapping '\x1f88' s = Yield '\x1f00' (CC s '\x03b9' '\x0000')
--- GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI
-foldMapping '\x1f89' s = Yield '\x1f01' (CC s '\x03b9' '\x0000')
--- GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI
-foldMapping '\x1f8a' s = Yield '\x1f02' (CC s '\x03b9' '\x0000')
--- GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI
-foldMapping '\x1f8b' s = Yield '\x1f03' (CC s '\x03b9' '\x0000')
--- GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI
-foldMapping '\x1f8c' s = Yield '\x1f04' (CC s '\x03b9' '\x0000')
--- GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI
-foldMapping '\x1f8d' s = Yield '\x1f05' (CC s '\x03b9' '\x0000')
--- GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
-foldMapping '\x1f8e' s = Yield '\x1f06' (CC s '\x03b9' '\x0000')
--- GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
-foldMapping '\x1f8f' s = Yield '\x1f07' (CC s '\x03b9' '\x0000')
--- GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI
-foldMapping '\x1f90' s = Yield '\x1f20' (CC s '\x03b9' '\x0000')
--- GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI
-foldMapping '\x1f91' s = Yield '\x1f21' (CC s '\x03b9' '\x0000')
--- GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI
-foldMapping '\x1f92' s = Yield '\x1f22' (CC s '\x03b9' '\x0000')
--- GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI
-foldMapping '\x1f93' s = Yield '\x1f23' (CC s '\x03b9' '\x0000')
--- GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI
-foldMapping '\x1f94' s = Yield '\x1f24' (CC s '\x03b9' '\x0000')
--- GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI
-foldMapping '\x1f95' s = Yield '\x1f25' (CC s '\x03b9' '\x0000')
--- GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
-foldMapping '\x1f96' s = Yield '\x1f26' (CC s '\x03b9' '\x0000')
--- GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
-foldMapping '\x1f97' s = Yield '\x1f27' (CC s '\x03b9' '\x0000')
--- GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI
-foldMapping '\x1f98' s = Yield '\x1f20' (CC s '\x03b9' '\x0000')
--- GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI
-foldMapping '\x1f99' s = Yield '\x1f21' (CC s '\x03b9' '\x0000')
--- GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI
-foldMapping '\x1f9a' s = Yield '\x1f22' (CC s '\x03b9' '\x0000')
--- GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI
-foldMapping '\x1f9b' s = Yield '\x1f23' (CC s '\x03b9' '\x0000')
--- GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI
-foldMapping '\x1f9c' s = Yield '\x1f24' (CC s '\x03b9' '\x0000')
--- GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI
-foldMapping '\x1f9d' s = Yield '\x1f25' (CC s '\x03b9' '\x0000')
--- GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
-foldMapping '\x1f9e' s = Yield '\x1f26' (CC s '\x03b9' '\x0000')
--- GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
-foldMapping '\x1f9f' s = Yield '\x1f27' (CC s '\x03b9' '\x0000')
--- GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI
-foldMapping '\x1fa0' s = Yield '\x1f60' (CC s '\x03b9' '\x0000')
--- GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI
-foldMapping '\x1fa1' s = Yield '\x1f61' (CC s '\x03b9' '\x0000')
--- GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI
-foldMapping '\x1fa2' s = Yield '\x1f62' (CC s '\x03b9' '\x0000')
--- GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI
-foldMapping '\x1fa3' s = Yield '\x1f63' (CC s '\x03b9' '\x0000')
--- GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI
-foldMapping '\x1fa4' s = Yield '\x1f64' (CC s '\x03b9' '\x0000')
--- GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI
-foldMapping '\x1fa5' s = Yield '\x1f65' (CC s '\x03b9' '\x0000')
--- GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
-foldMapping '\x1fa6' s = Yield '\x1f66' (CC s '\x03b9' '\x0000')
--- GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
-foldMapping '\x1fa7' s = Yield '\x1f67' (CC s '\x03b9' '\x0000')
--- GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI
-foldMapping '\x1fa8' s = Yield '\x1f60' (CC s '\x03b9' '\x0000')
--- GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI
-foldMapping '\x1fa9' s = Yield '\x1f61' (CC s '\x03b9' '\x0000')
--- GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI
-foldMapping '\x1faa' s = Yield '\x1f62' (CC s '\x03b9' '\x0000')
--- GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI
-foldMapping '\x1fab' s = Yield '\x1f63' (CC s '\x03b9' '\x0000')
--- GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI
-foldMapping '\x1fac' s = Yield '\x1f64' (CC s '\x03b9' '\x0000')
--- GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI
-foldMapping '\x1fad' s = Yield '\x1f65' (CC s '\x03b9' '\x0000')
--- GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
-foldMapping '\x1fae' s = Yield '\x1f66' (CC s '\x03b9' '\x0000')
--- GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
-foldMapping '\x1faf' s = Yield '\x1f67' (CC s '\x03b9' '\x0000')
--- GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI
-foldMapping '\x1fb2' s = Yield '\x1f70' (CC s '\x03b9' '\x0000')
--- GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI
-foldMapping '\x1fb3' s = Yield '\x03b1' (CC s '\x03b9' '\x0000')
--- GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI
-foldMapping '\x1fb4' s = Yield '\x03ac' (CC s '\x03b9' '\x0000')
--- GREEK SMALL LETTER ALPHA WITH PERISPOMENI
-foldMapping '\x1fb6' s = Yield '\x03b1' (CC s '\x0342' '\x0000')
--- GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI
-foldMapping '\x1fb7' s = Yield '\x03b1' (CC s '\x0342' '\x03b9')
--- GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI
-foldMapping '\x1fbc' s = Yield '\x03b1' (CC s '\x03b9' '\x0000')
--- GREEK PROSGEGRAMMENI
-foldMapping '\x1fbe' s = Yield '\x03b9' (CC s '\x0000' '\x0000')
--- GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI
-foldMapping '\x1fc2' s = Yield '\x1f74' (CC s '\x03b9' '\x0000')
--- GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI
-foldMapping '\x1fc3' s = Yield '\x03b7' (CC s '\x03b9' '\x0000')
--- GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI
-foldMapping '\x1fc4' s = Yield '\x03ae' (CC s '\x03b9' '\x0000')
--- GREEK SMALL LETTER ETA WITH PERISPOMENI
-foldMapping '\x1fc6' s = Yield '\x03b7' (CC s '\x0342' '\x0000')
--- GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI
-foldMapping '\x1fc7' s = Yield '\x03b7' (CC s '\x0342' '\x03b9')
--- GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI
-foldMapping '\x1fcc' s = Yield '\x03b7' (CC s '\x03b9' '\x0000')
--- GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA
-foldMapping '\x1fd2' s = Yield '\x03b9' (CC s '\x0308' '\x0300')
--- GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA
-foldMapping '\x1fd3' s = Yield '\x03b9' (CC s '\x0308' '\x0301')
--- GREEK SMALL LETTER IOTA WITH PERISPOMENI
-foldMapping '\x1fd6' s = Yield '\x03b9' (CC s '\x0342' '\x0000')
--- GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI
-foldMapping '\x1fd7' s = Yield '\x03b9' (CC s '\x0308' '\x0342')
--- GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA
-foldMapping '\x1fe2' s = Yield '\x03c5' (CC s '\x0308' '\x0300')
--- GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA
-foldMapping '\x1fe3' s = Yield '\x03c5' (CC s '\x0308' '\x0301')
--- GREEK SMALL LETTER RHO WITH PSILI
-foldMapping '\x1fe4' s = Yield '\x03c1' (CC s '\x0313' '\x0000')
--- GREEK SMALL LETTER UPSILON WITH PERISPOMENI
-foldMapping '\x1fe6' s = Yield '\x03c5' (CC s '\x0342' '\x0000')
--- GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI
-foldMapping '\x1fe7' s = Yield '\x03c5' (CC s '\x0308' '\x0342')
--- GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI
-foldMapping '\x1ff2' s = Yield '\x1f7c' (CC s '\x03b9' '\x0000')
--- GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI
-foldMapping '\x1ff3' s = Yield '\x03c9' (CC s '\x03b9' '\x0000')
--- GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI
-foldMapping '\x1ff4' s = Yield '\x03ce' (CC s '\x03b9' '\x0000')
--- GREEK SMALL LETTER OMEGA WITH PERISPOMENI
-foldMapping '\x1ff6' s = Yield '\x03c9' (CC s '\x0342' '\x0000')
--- GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI
-foldMapping '\x1ff7' s = Yield '\x03c9' (CC s '\x0342' '\x03b9')
--- GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI
-foldMapping '\x1ffc' s = Yield '\x03c9' (CC s '\x03b9' '\x0000')
--- COPTIC CAPITAL LETTER BOHAIRIC KHEI
-foldMapping '\x2cf2' s = Yield '\x2cf3' (CC s '\x0000' '\x0000')
--- LATIN CAPITAL LETTER C WITH BAR
-foldMapping '\xa792' s = Yield '\xa793' (CC s '\x0000' '\x0000')
--- LATIN CAPITAL LETTER H WITH HOOK
-foldMapping '\xa7aa' s = Yield '\x0266' (CC s '\x0000' '\x0000')
--- LATIN SMALL LIGATURE FF
-foldMapping '\xfb00' s = Yield '\x0066' (CC s '\x0066' '\x0000')
--- LATIN SMALL LIGATURE FI
-foldMapping '\xfb01' s = Yield '\x0066' (CC s '\x0069' '\x0000')
--- LATIN SMALL LIGATURE FL
-foldMapping '\xfb02' s = Yield '\x0066' (CC s '\x006c' '\x0000')
--- LATIN SMALL LIGATURE FFI
-foldMapping '\xfb03' s = Yield '\x0066' (CC s '\x0066' '\x0069')
--- LATIN SMALL LIGATURE FFL
-foldMapping '\xfb04' s = Yield '\x0066' (CC s '\x0066' '\x006c')
--- LATIN SMALL LIGATURE LONG S T
-foldMapping '\xfb05' s = Yield '\x0073' (CC s '\x0074' '\x0000')
--- LATIN SMALL LIGATURE ST
-foldMapping '\xfb06' s = Yield '\x0073' (CC s '\x0074' '\x0000')
--- ARMENIAN SMALL LIGATURE MEN NOW
-foldMapping '\xfb13' s = Yield '\x0574' (CC s '\x0576' '\x0000')
--- ARMENIAN SMALL LIGATURE MEN ECH
-foldMapping '\xfb14' s = Yield '\x0574' (CC s '\x0565' '\x0000')
--- ARMENIAN SMALL LIGATURE MEN INI
-foldMapping '\xfb15' s = Yield '\x0574' (CC s '\x056b' '\x0000')
--- ARMENIAN SMALL LIGATURE VEW NOW
-foldMapping '\xfb16' s = Yield '\x057e' (CC s '\x0576' '\x0000')
--- ARMENIAN SMALL LIGATURE MEN XEH
-foldMapping '\xfb17' s = Yield '\x0574' (CC s '\x056d' '\x0000')
-foldMapping c s = Yield (toLower c) (CC s '\0' '\0')

Data/Text/Fusion/Common.hs

-{-# LANGUAGE BangPatterns, MagicHash, Rank2Types #-}
--- |
--- Module      : Data.Text.Fusion.Common
--- Copyright   : (c) Bryan O'Sullivan 2009, 2012
---
--- License     : BSD-style
--- Maintainer  : bos@serpentine.com, rtomharper@googlemail.com,
---               duncan@haskell.org
--- Stability   : experimental
--- Portability : GHC
---
--- Common stream fusion functionality for text.
-
-module Data.Text.Fusion.Common
-    (
-    -- * Creation and elimination
-      singleton
-    , streamList
-    , unstreamList
-    , streamCString#
-
-    -- * Basic interface
-    , cons
-    , snoc
-    , append
-    , head
-    , uncons
-    , last
-    , tail
-    , init
-    , null
-    , lengthI
-    , compareLengthI
-    , isSingleton
-
-    -- * Transformations
-    , map
-    , intercalate
-    , intersperse
-
-    -- ** Case conversion
-    -- $case
-    , toCaseFold
-    , toLower
-    , toTitle
-    , toUpper
-
-    -- ** Justification
-    , justifyLeftI
-
-    -- * Folds
-    , foldl
-    , foldl'
-    , foldl1
-    , foldl1'
-    , foldr
-    , foldr1
-
-    -- ** Special folds
-    , concat
-    , concatMap
-    , any
-    , all
-    , maximum
-    , minimum
-
-    -- * Construction
-    -- ** Scans
-    , scanl
-
-    -- ** Accumulating maps
-    -- , mapAccumL
-
-    -- ** Generation and unfolding
-    , replicateCharI
-    , replicateI
-    , unfoldr
-    , unfoldrNI
-
-    -- * Substrings
-    -- ** Breaking strings
-    , take
-    , drop
-    , takeWhile
-    , dropWhile
-
-    -- * Predicates
-    , isPrefixOf
-
-    -- * Searching
-    , elem
-    , filter
-
-    -- * Indexing
-    , findBy
-    , indexI
-    , findIndexI
-    , countCharI
-
-    -- * Zipping and unzipping
-    , zipWith
-    ) where
-
-import Prelude (Bool(..), Char, Eq(..), Int, Integral, Maybe(..),
-                Ord(..), Ordering(..), String, (.), ($), (+), (-), (*), (++),
-                (&&), fromIntegral, not, otherwise)
-import qualified Data.List as L
-import qualified Prelude as P
-import Data.Bits (shiftL)
-import Data.Char (isLetter)
-import Data.Int (Int64)
-import Data.Text.Fusion.Internal
-import Data.Text.Fusion.CaseMapping (foldMapping, lowerMapping, titleMapping,
-                                     upperMapping)
-import Data.Text.Fusion.Size
-import GHC.Prim (Addr#, chr#, indexCharOffAddr#, ord#)
-import GHC.Types (Char(..), Int(..))
-
-singleton :: Char -> Stream Char
-singleton c = Stream next False 1
-    where next False = Yield c True
-          next True  = Done
-{-# INLINE singleton #-}
-
-streamList :: [a] -> Stream a
-{-# INLINE [0] streamList #-}
-streamList s  = Stream next s unknownSize
-    where next []       = Done
-          next (x:xs)   = Yield x xs
-
-unstreamList :: Stream a -> [a]
-unstreamList (Stream next s0 _len) = unfold s0
-    where unfold !s = case next s of
-                        Done       -> []
-                        Skip s'    -> unfold s'
-                        Yield x s' -> x : unfold s'
-{-# INLINE [0] unstreamList #-}
-
-{-# RULES "STREAM streamList/unstreamList fusion" forall s. streamList (unstreamList s) = s #-}
-
--- | Stream the UTF-8-like packed encoding used by GHC to represent
--- constant strings in generated code.
---
--- This encoding uses the byte sequence "\xc0\x80" to represent NUL,
--- and the string is NUL-terminated.
-streamCString# :: Addr# -> Stream Char
-streamCString# addr = Stream step 0 unknownSize
-  where
-    step !i
-        | b == 0    = Done
-        | b <= 0x7f = Yield (C# b#) (i+1)
-        | b <= 0xdf = let !c = chr $ ((b-0xc0) `shiftL` 6) + next 1
-                      in Yield c (i+2)
-        | b <= 0xef = let !c = chr $ ((b-0xe0) `shiftL` 12) +
-                                      (next 1  `shiftL` 6) +
-                                       next 2
-                      in Yield c (i+3)
-        | otherwise = let !c = chr $ ((b-0xf0) `shiftL` 18) +
-                                      (next 1  `shiftL` 12) +
-                                      (next 2  `shiftL` 6) +
-                                       next 3
-                      in Yield c (i+4)
-      where b      = I# (ord# b#)
-            next n = I# (ord# (at# (i+n))) - 0x80
-            !b#    = at# i
-    at# (I# i#) = indexCharOffAddr# addr i#
-    chr (I# i#) = C# (chr# i#)
-{-# INLINE [0] streamCString# #-}
-
--- ----------------------------------------------------------------------------
--- * Basic stream functions
-
-data C s = C0 !s
-         | C1 !s
-
--- | /O(n)/ Adds a character to the front of a Stream Char.
-cons :: Char -> Stream Char -> Stream Char
-cons !w (Stream next0 s0 len) = Stream next (C1 s0) (len+1)
-    where
-      next (C1 s) = Yield w (C0 s)
-      next (C0 s) = case next0 s of
-                          Done -> Done
-                          Skip s' -> Skip (C0 s')
-                          Yield x s' -> Yield x (C0 s')
-{-# INLINE [0] cons #-}
-
--- | /O(n)/ Adds a character to the end of a stream.
-snoc :: Stream Char -> Char -> Stream Char
-snoc (Stream next0 xs0 len) w = Stream next (J xs0) (len+1)
-  where
-    next (J xs) = case next0 xs of
-      Done        -> Yield w N
-      Skip xs'    -> Skip    (J xs')
-      Yield x xs' -> Yield x (J xs')
-    next N = Done
-{-# INLINE [0] snoc #-}
-
-data E l r = L !l
-           | R !r
-
--- | /O(n)/ Appends one Stream to the other.
-append :: Stream Char -> Stream Char -> Stream Char
-append (Stream next0 s01 len1) (Stream next1 s02 len2) =
-    Stream next (L s01) (len1 + len2)
-    where
-      next (L s1) = case next0 s1 of
-                         Done        -> Skip    (R s02)
-                         Skip s1'    -> Skip    (L s1')
-                         Yield x s1' -> Yield x (L s1')
-      next (R s2) = case next1 s2 of
-                          Done        -> Done
-                          Skip s2'    -> Skip    (R s2')
-                          Yield x s2' -> Yield x (R s2')
-{-# INLINE [0] append #-}
-
--- | /O(1)/ Returns the first character of a Text, which must be non-empty.
--- Subject to array fusion.
-head :: Stream Char -> Char
-head (Stream next s0 _len) = loop_head s0
-    where
-      loop_head !s = case next s of
-                      Yield x _ -> x
-                      Skip s'   -> loop_head s'
-                      Done      -> head_empty
-{-# INLINE [0] head #-}
-
-head_empty :: a
-head_empty = streamError "head" "Empty stream"
-{-# NOINLINE head_empty #-}
-
--- | /O(1)/ Returns the first character and remainder of a 'Stream
--- Char', or 'Nothing' if empty.  Subject to array fusion.
-uncons :: Stream Char -> Maybe (Char, Stream Char)
-uncons (Stream next s0 len) = loop_uncons s0
-    where
-      loop_uncons !s = case next s of
-                         Yield x s1 -> Just (x, Stream next s1 (len-1))
-                         Skip s'    -> loop_uncons s'
-                         Done       -> Nothing
-{-# INLINE [0] uncons #-}
-
--- | /O(n)/ Returns the last character of a 'Stream Char', which must
--- be non-empty.
-last :: Stream Char -> Char
-last (Stream next s0 _len) = loop0_last s0
-    where
-      loop0_last !s = case next s of
-                        Done       -> emptyError "last"
-                        Skip s'    -> loop0_last  s'
-                        Yield x s' -> loop_last x s'
-      loop_last !x !s = case next s of
-                         Done        -> x
-                         Skip s'     -> loop_last x  s'
-                         Yield x' s' -> loop_last x' s'
-{-# INLINE[0] last #-}
-
--- | /O(1)/ Returns all characters after the head of a Stream Char, which must
--- be non-empty.
-tail :: Stream Char -> Stream Char
-tail (Stream next0 s0 len) = Stream next (C0 s0) (len-1)
-    where
-      next (C0 s) = case next0 s of
-                      Done       -> emptyError "tail"
-                      Skip s'    -> Skip (C0 s')
-                      Yield _ s' -> Skip (C1 s')
-      next (C1 s) = case next0 s of
-                      Done       -> Done
-                      Skip s'    -> Skip    (C1 s')
-                      Yield x s' -> Yield x (C1 s')
-{-# INLINE [0] tail #-}
-
-data Init s = Init0 !s
-            | Init1 {-# UNPACK #-} !Char !s
-
--- | /O(1)/ Returns all but the last character of a Stream Char, which
--- must be non-empty.
-init :: Stream Char -> Stream Char
-init (Stream next0 s0 len) = Stream next (Init0 s0) (len-1)
-    where
-      next (Init0 s) = case next0 s of
-                         Done       -> emptyError "init"
-                         Skip s'    -> Skip (Init0 s')
-                         Yield x s' -> Skip (Init1 x s')
-      next (Init1 x s)  = case next0 s of
-                            Done        -> Done
-                            Skip s'     -> Skip    (Init1 x s')
-                            Yield x' s' -> Yield x (Init1 x' s')
-{-# INLINE [0] init #-}
-
--- | /O(1)/ Tests whether a Stream Char is empty or not.
-null :: Stream Char -> Bool
-null (Stream next s0 _len) = loop_null s0
-    where
-      loop_null !s = case next s of
-                       Done      -> True
-                       Yield _ _ -> False
-                       Skip s'   -> loop_null s'
-{-# INLINE[0] null #-}
-
--- | /O(n)/ Returns the number of characters in a string.
-lengthI :: Integral a => Stream Char -> a
-lengthI (Stream next s0 _len) = loop_length 0 s0
-    where
-      loop_length !z s  = case next s of
-                           Done       -> z
-                           Skip    s' -> loop_length z s'
-                           Yield _ s' -> loop_length (z + 1) s'
-{-# INLINE[0] lengthI #-}
-
--- | /O(n)/ Compares the count of characters in a string to a number.
--- Subject to fusion.
---
--- This function gives the same answer as comparing against the result
--- of 'lengthI', but can short circuit if the count of characters is
--- greater than the number, and hence be more efficient.
-compareLengthI :: Integral a => Stream Char -> a -> Ordering
-compareLengthI (Stream next s0 len) n =
-    case exactly len of
-      Nothing -> loop_cmp 0 s0
-      Just i  -> compare (fromIntegral i) n
-    where
-      loop_cmp !z s  = case next s of
-                         Done       -> compare z n
-                         Skip    s' -> loop_cmp z s'
-                         Yield _ s' | z > n     -> GT
-                                    | otherwise -> loop_cmp (z + 1) s'
-{-# INLINE[0] compareLengthI #-}
-
--- | /O(n)/ Indicate whether a string contains exactly one element.
-isSingleton :: Stream Char -> Bool
-isSingleton (Stream next s0 _len) = loop 0 s0
-    where
-      loop !z s  = case next s of
-                     Done            -> z == (1::Int)
-                     Skip    s'      -> loop z s'
-                     Yield _ s'
-                         | z >= 1    -> False
-                         | otherwise -> loop (z+1) s'
-{-# INLINE[0] isSingleton #-}
-
--- ----------------------------------------------------------------------------
--- * Stream transformations
-
--- | /O(n)/ 'map' @f @xs is the Stream Char obtained by applying @f@
--- to each element of @xs@.
-map :: (Char -> Char) -> Stream Char -> Stream Char
-map f (Stream next0 s0 len) = Stream next s0 len
-    where
-      next !s = case next0 s of
-                  Done       -> Done
-                  Skip s'    -> Skip s'
-                  Yield x s' -> Yield (f x) s'
-{-# INLINE [0] map #-}
-
-{-#
-  RULES "STREAM map/map fusion" forall f g s.
-     map f (map g s) = map (\x -> f (g x)) s
- #-}
-
-data I s = I1 !s
-         | I2 !s {-# UNPACK #-} !Char
-         | I3 !s
-
--- | /O(n)/ Take a character and place it between each of the
--- characters of a 'Stream Char'.
-intersperse :: Char -> Stream Char -> Stream Char
-intersperse c (Stream next0 s0 len) = Stream next (I1 s0) len
-    where
-      next (I1 s) = case next0 s of
-        Done       -> Done
-        Skip s'    -> Skip (I1 s')
-        Yield x s' -> Skip (I2 s' x)
-      next (I2 s x)  = Yield x (I3 s)
-      next (I3 s) = case next0 s of
-        Done       -> Done
-        Skip s'    -> Skip    (I3 s')
-        Yield x s' -> Yield c (I2 s' x)
-{-# INLINE [0] intersperse #-}
-
--- ----------------------------------------------------------------------------
--- ** Case conversions (folds)
-
--- $case
---
--- With Unicode text, it is incorrect to use combinators like @map
--- toUpper@ to case convert each character of a string individually.
--- Instead, use the whole-string case conversion functions from this
--- module.  For correctness in different writing systems, these
--- functions may map one input character to two or three output
--- characters.
-
-caseConvert :: (forall s. Char -> s -> Step (CC s) Char)
-            -> Stream Char -> Stream Char
-caseConvert remap (Stream next0 s0 len) = Stream next (CC s0 '\0' '\0') len
-  where
-    next (CC s '\0' _) =
-        case next0 s of
-          Done       -> Done
-          Skip s'    -> Skip (CC s' '\0' '\0')
-          Yield c s' -> remap c s'
-    next (CC s a b)  =  Yield a (CC s b '\0')
-
--- | /O(n)/ Convert a string to folded case.  This function is mainly
--- useful for performing caseless (or case insensitive) string
--- comparisons.
---
--- A string @x@ is a caseless match for a string @y@ if and only if:
---
--- @toCaseFold x == toCaseFold y@
---
--- The result string may be longer than the input string, and may
--- differ from applying 'toLower' to the input string.  For instance,
--- the Armenian small ligature men now (U+FB13) is case folded to the
--- bigram men now (U+0574 U+0576), while the micro sign (U+00B5) is
--- case folded to the Greek small letter letter mu (U+03BC) instead of
--- itself.
-toCaseFold :: Stream Char -> Stream Char
-toCaseFold = caseConvert foldMapping
-{-# INLINE [0] toCaseFold #-}
-
--- | /O(n)/ Convert a string to upper case, using simple case
--- conversion.  The result string may be longer than the input string.
--- For instance, the German eszett (U+00DF) maps to the two-letter
--- sequence SS.
-toUpper :: Stream Char -> Stream Char
-toUpper = caseConvert upperMapping
-{-# INLINE [0] toUpper #-}
-
--- | /O(n)/ Convert a string to lower case, using simple case
--- conversion.  The result string may be longer than the input string.
--- For instance, the Latin capital letter I with dot above (U+0130)
--- maps to the sequence Latin small letter i (U+0069) followed by
--- combining dot above (U+0307).
-toLower :: Stream Char -> Stream Char
-toLower = caseConvert lowerMapping
-{-# INLINE [0] toLower #-}
-
--- | /O(n)/ Convert a string to title case, using simple case
--- conversion.
---
--- The first letter of the input is converted to title case, as is
--- every subsequent letter that immediately follows a non-letter.
--- Every letter that immediately follows another letter is converted
--- to lower case.
---
--- The result string may be longer than the input string. For example,
--- the Latin small ligature &#xfb02; (U+FB02) is converted to the
--- sequence Latin capital letter F (U+0046) followed by Latin small
--- letter l (U+006C).
---
--- /Note/: this function does not take language or culture specific
--- rules into account. For instance, in English, different style
--- guides disagree on whether the book name \"The Hill of the Red
--- Fox\" is correctly title cased&#x2014;but this function will
--- capitalize /every/ word.
-toTitle :: Stream Char -> Stream Char
-toTitle (Stream next0 s0 len) = Stream next (CC (False :*: s0) '\0' '\0') len
-  where
-    next (CC (letter :*: s) '\0' _) =
-      case next0 s of
-        Done           -> Done
-        Skip s'        -> Skip (CC (letter :*: s') '\0' '\0')
-        Yield c s'
-          | letter'    -> if letter
-                          then lowerMapping c (letter' :*: s')
-                          else titleMapping c (letter' :*: s')
-          | otherwise  -> Yield c (CC (letter' :*: s') '\0' '\0')
-          where letter' = isLetter c
-    next (CC s a b)     = Yield a (CC s b '\0')
-{-# INLINE [0] toTitle #-}
-
-justifyLeftI :: Integral a => a -> Char -> Stream Char -> Stream Char
-justifyLeftI k c (Stream next0 s0 len) =
-    Stream next (s0 :*: S1 :*: 0) (larger (fromIntegral k) len)
-  where
-    next (s :*: S1 :*: n) =
-        case next0 s of
-          Done       -> next (s :*: S2 :*: n)
-          Skip s'    -> Skip (s' :*: S1 :*: n)
-          Yield x s' -> Yield x (s' :*: S1 :*: n+1)
-    next (s :*: S2 :*: n)
-        | n < k       = Yield c (s :*: S2 :*: n+1)
-        | otherwise   = Done
-    {-# INLINE next #-}
-{-# INLINE [0] justifyLeftI #-}
-
--- ----------------------------------------------------------------------------
--- * Reducing Streams (folds)
-
--- | foldl, applied to a binary operator, a starting value (typically the
--- left-identity of the operator), and a Stream, reduces the Stream using the
--- binary operator, from left to right.
-foldl :: (b -> Char -> b) -> b -> Stream Char -> b
-foldl f z0 (Stream next s0 _len) = loop_foldl z0 s0
-    where
-      loop_foldl z !s = case next s of
-                          Done -> z
-                          Skip s' -> loop_foldl z s'
-                          Yield x s' -> loop_foldl (f z x) s'
-{-# INLINE [0] foldl #-}
-
--- | A strict version of foldl.
-foldl' :: (b -> Char -> b) -> b -> Stream Char -> b
-foldl' f z0 (Stream next s0 _len) = loop_foldl' z0 s0
-    where
-      loop_foldl' !z !s = case next s of
-                            Done -> z
-                            Skip s' -> loop_foldl' z s'
-                            Yield x s' -> loop_foldl' (f z x) s'
-{-# INLINE [0] foldl' #-}
-
--- | foldl1 is a variant of foldl that has no starting value argument,
--- and thus must be applied to non-empty Streams.
-foldl1 :: (Char -> Char -> Char) -> Stream Char -> Char
-foldl1 f (Stream next s0 _len) = loop0_foldl1 s0
-    where
-      loop0_foldl1 !s = case next s of
-                          Skip s' -> loop0_foldl1 s'
-                          Yield x s' -> loop_foldl1 x s'
-                          Done -> emptyError "foldl1"
-      loop_foldl1 z !s = case next s of
-                           Done -> z
-                           Skip s' -> loop_foldl1 z s'
-                           Yield x s' -> loop_foldl1 (f z x) s'
-{-# INLINE [0] foldl1 #-}
-
--- | A strict version of foldl1.
-foldl1' :: (Char -> Char -> Char) -> Stream Char -> Char
-foldl1' f (Stream next s0 _len) = loop0_foldl1' s0
-    where
-      loop0_foldl1' !s = case next s of
-                           Skip s' -> loop0_foldl1' s'
-                           Yield x s' -> loop_foldl1' x s'
-                           Done -> emptyError "foldl1"
-      loop_foldl1' !z !s = case next s of
-                             Done -> z
-                             Skip s' -> loop_foldl1' z s'
-                             Yield x s' -> loop_foldl1' (f z x) s'
-{-# INLINE [0] foldl1' #-}
-
--- | 'foldr', applied to a binary operator, a starting value (typically the
--- right-identity of the operator), and a stream, reduces the stream using the
--- binary operator, from right to left.
-foldr :: (Char -> b -> b) -> b -> Stream Char -> b
-foldr f z (Stream next s0 _len) = loop_foldr s0
-    where
-      loop_foldr !s = case next s of
-                        Done -> z
-                        Skip s' -> loop_foldr s'
-                        Yield x s' -> f x (loop_foldr s')
-{-# INLINE [0] foldr #-}
-
--- | foldr1 is a variant of 'foldr' that has no starting value argument,
--- and thus must be applied to non-empty streams.
--- Subject to array fusion.
-foldr1 :: (Char -> Char -> Char) -> Stream Char -> Char
-foldr1 f (Stream next s0 _len) = loop0_foldr1 s0
-  where
-    loop0_foldr1 !s = case next s of
-      Done       -> emptyError "foldr1"
-      Skip    s' -> loop0_foldr1  s'
-      Yield x s' -> loop_foldr1 x s'
-
-    loop_foldr1 x !s = case next s of
-      Done        -> x
-      Skip     s' -> loop_foldr1 x s'
-      Yield x' s' -> f x (loop_foldr1 x' s')
-{-# INLINE [0] foldr1 #-}
-
-intercalate :: Stream Char -> [Stream Char] -> Stream Char
-intercalate s = concat . (L.intersperse s)
-{-# INLINE [0] intercalate #-}
-
--- ----------------------------------------------------------------------------
--- ** Special folds
-
--- | /O(n)/ Concatenate a list of streams. Subject to array fusion.
-concat :: [Stream Char] -> Stream Char
-concat = L.foldr append empty
-{-# INLINE [0] concat #-}
-
--- | Map a function over a stream that results in a stream and concatenate the
--- results.
-concatMap :: (Char -> Stream Char) -> Stream Char -> Stream Char
-concatMap f = foldr (append . f) empty
-{-# INLINE [0] concatMap #-}
-
--- | /O(n)/ any @p @xs determines if any character in the stream
--- @xs@ satisifes the predicate @p@.
-any :: (Char -> Bool) -> Stream Char -> Bool
-any p (Stream next0 s0 _len) = loop_any s0
-    where
-      loop_any !s = case next0 s of
-                      Done                   -> False
-                      Skip s'                -> loop_any s'
-                      Yield x s' | p x       -> True
-                                 | otherwise -> loop_any s'
-{-# INLINE [0] any #-}
-
--- | /O(n)/ all @p @xs determines if all characters in the 'Text'
--- @xs@ satisify the predicate @p@.
-all :: (Char -> Bool) -> Stream Char -> Bool
-all p (Stream next0 s0 _len) = loop_all s0
-    where
-      loop_all !s = case next0 s of
-                      Done                   -> True
-                      Skip s'                -> loop_all s'
-                      Yield x s' | p x       -> loop_all s'
-                                 | otherwise -> False
-{-# INLINE [0] all #-}
-
--- | /O(n)/ maximum returns the maximum value from a stream, which must be
--- non-empty.
-maximum :: Stream Char -> Char
-maximum (Stream next0 s0 _len) = loop0_maximum s0
-    where
-      loop0_maximum !s   = case next0 s of
-                             Done       -> emptyError "maximum"
-                             Skip s'    -> loop0_maximum s'
-                             Yield x s' -> loop_maximum x s'
-      loop_maximum !z !s = case next0 s of
-                             Done            -> z
-                             Skip s'         -> loop_maximum z s'
-                             Yield x s'
-                                 | x > z     -> loop_maximum x s'
-                                 | otherwise -> loop_maximum z s'
-{-# INLINE [0] maximum #-}
-
--- | /O(n)/ minimum returns the minimum value from a 'Text', which must be
--- non-empty.
-minimum :: Stream Char -> Char
-minimum (Stream next0 s0 _len) = loop0_minimum s0
-    where
-      loop0_minimum !s   = case next0 s of
-                             Done       -> emptyError "minimum"
-                             Skip s'    -> loop0_minimum s'
-                             Yield x s' -> loop_minimum x s'
-      loop_minimum !z !s = case next0 s of
-                             Done            -> z
-                             Skip s'         -> loop_minimum z s'
-                             Yield x s'
-                                 | x < z     -> loop_minimum x s'
-                                 | otherwise -> loop_minimum z s'
-{-# INLINE [0] minimum #-}
-
--- -----------------------------------------------------------------------------
--- * Building streams
-
-scanl :: (Char -> Char -> Char) -> Char -> Stream Char -> Stream Char
-scanl f z0 (Stream next0 s0 len) = Stream next (S1 :*: z0 :*: s0) (len+1) -- HINT maybe too low
-  where
-    {-# INLINE next #-}
-    next (S1 :*: z :*: s) = Yield z (S2 :*: z :*: s)
-    next (S2 :*: z :*: s) = case next0 s of
-                              Yield x s' -> let !x' = f z x
-                                            in Yield x' (S2 :*: x' :*: s')
-                              Skip s'    -> Skip (S2 :*: z :*: s')
-                              Done       -> Done
-{-# INLINE [0] scanl #-}
-
--- -----------------------------------------------------------------------------
--- ** Accumulating maps
-
-{-
--- | /O(n)/ Like a combination of 'map' and 'foldl'. Applies a
--- function to each element of a stream, passing an accumulating
--- parameter from left to right, and returns a final stream.
---
--- /Note/: Unlike the version over lists, this function does not
--- return a final value for the accumulator, because the nature of
--- streams precludes it.
-mapAccumL :: (a -> b -> (a,b)) -> a -> Stream b -> Stream b
-mapAccumL f z0 (Stream next0 s0 len) = Stream next (s0 :*: z0) len -- HINT depends on f
-  where
-    {-# INLINE next #-}
-    next (s :*: z) = case next0 s of
-                       Yield x s' -> let (z',y) = f z x
-                                     in Yield y (s' :*: z')
-                       Skip s'    -> Skip (s' :*: z)
-                       Done       -> Done
-{-# INLINE [0] mapAccumL #-}
--}
-
--- -----------------------------------------------------------------------------
--- ** Generating and unfolding streams
-
-replicateCharI :: Integral a => a -> Char -> Stream Char
-replicateCharI n c
-    | n < 0     = empty
-    | otherwise = Stream next 0 (fromIntegral n) -- HINT maybe too low
-  where
-    next i | i >= n    = Done
-           | otherwise = Yield c (i + 1)
-{-# INLINE [0] replicateCharI #-}
-
-data RI s = RI !s {-# UNPACK #-} !Int64
-
-replicateI :: Int64 -> Stream Char -> Stream Char
-replicateI n (Stream next0 s0 len) =
-    Stream next (RI s0 0) (fromIntegral (max 0 n) * len)
-  where
-    next (RI s k)
-        | k >= n = Done
-        | otherwise = case next0 s of
-                        Done       -> Skip    (RI s0 (k+1))
-                        Skip s'    -> Skip    (RI s' k)
-                        Yield x s' -> Yield x (RI s' k)
-{-# INLINE [0] replicateI #-}
-
--- | /O(n)/, where @n@ is the length of the result. The unfoldr function
--- is analogous to the List 'unfoldr'. unfoldr builds a stream
--- from a seed value. The function takes the element and returns
--- Nothing if it is done producing the stream or returns Just
--- (a,b), in which case, a is the next Char in the string, and b is
--- the seed value for further production.
-unfoldr :: (a -> Maybe (Char,a)) -> a -> Stream Char
-unfoldr f s0 = Stream next s0 1 -- HINT maybe too low
-    where
-      {-# INLINE next #-}
-      next !s = case f s of
-                 Nothing      -> Done
-                 Just (w, s') -> Yield w s'
-{-# INLINE [0] unfoldr #-}
-
--- | /O(n)/ Like 'unfoldr', 'unfoldrNI' builds a stream from a seed
--- value. However, the length of the result is limited by the
--- first argument to 'unfoldrNI'. This function is more efficient than
--- 'unfoldr' when the length of the result is known.
-unfoldrNI :: Integral a => a -> (b -> Maybe (Char,b)) -> b -> Stream Char
-unfoldrNI n f s0 | n <  0    = empty
-                 | otherwise = Stream next (0 :*: s0) (fromIntegral (n*2)) -- HINT maybe too high
-    where
-      {-# INLINE next #-}
-      next (z :*: s) = case f s of
-          Nothing                  -> Done
-          Just (w, s') | z >= n    -> Done
-                       | otherwise -> Yield w ((z + 1) :*: s')
-{-# INLINE unfoldrNI #-}
-
--------------------------------------------------------------------------------
---  * Substreams
-
--- | /O(n)/ take n, applied to a stream, returns the prefix of the
--- stream of length @n@, or the stream itself if @n@ is greater than the
--- length of the stream.
-take :: Integral a => a -> Stream Char -> Stream Char
-take n0 (Stream next0 s0 len) =
-    Stream next (n0 :*: s0) (smaller len (fromIntegral (max 0 n0)))
-    where
-      {-# INLINE next #-}
-      next (n :*: s) | n <= 0    = Done
-                     | otherwise = case next0 s of
-                                     Done -> Done
-                                     Skip s' -> Skip (n :*: s')
-                                     Yield x s' -> Yield x ((n-1) :*: s')
-{-# INLINE [0] take #-}
-
--- | /O(n)/ drop n, applied to a stream, returns the suffix of the
--- stream after the first @n@ characters, or the empty stream if @n@
--- is greater than the length of the stream.
-drop :: Integral a => a -> Stream Char -> Stream Char
-drop n0 (Stream next0 s0 len) =
-    Stream next (J n0 :*: s0) (len - fromIntegral (max 0 n0))
-  where
-    {-# INLINE next #-}
-    next (J n :*: s)
-      | n <= 0    = Skip (N :*: s)
-      | otherwise = case next0 s of
-          Done       -> Done
-          Skip    s' -> Skip (J n    :*: s')
-          Yield _ s' -> Skip (J (n-1) :*: s')
-    next (N :*: s) = case next0 s of
-      Done       -> Done
-      Skip    s' -> Skip    (N :*: s')
-      Yield x s' -> Yield x (N :*: s')
-{-# INLINE [0] drop #-}
-
--- | takeWhile, applied to a predicate @p@ and a stream, returns the
--- longest prefix (possibly empty) of elements that satisfy p.
-takeWhile :: (Char -> Bool) -> Stream Char -> Stream Char
-takeWhile p (Stream next0 s0 len) = Stream next s0 len -- HINT maybe too high
-    where
-      {-# INLINE next #-}
-      next !s = case next0 s of
-                  Done    -> Done
-                  Skip s' -> Skip s'
-                  Yield x s' | p x       -> Yield x s'
-                             | otherwise -> Done
-{-# INLINE [0] takeWhile #-}
-
--- | dropWhile @p @xs returns the suffix remaining after takeWhile @p @xs.
-dropWhile :: (Char -> Bool) -> Stream Char -> Stream Char
-dropWhile p (Stream next0 s0 len) = Stream next (S1 :*: s0) len -- HINT maybe too high
-    where
-    {-# INLINE next #-}
-    next (S1 :*: s)  = case next0 s of
-      Done                   -> Done
-      Skip    s'             -> Skip    (S1 :*: s')
-      Yield x s' | p x       -> Skip    (S1 :*: s')
-                 | otherwise -> Yield x (S2 :*: s')
-    next (S2 :*: s) = case next0 s of
-      Done       -> Done
-      Skip    s' -> Skip    (S2 :*: s')
-      Yield x s' -> Yield x (S2 :*: s')
-{-# INLINE [0] dropWhile #-}
-
--- | /O(n)/ The 'isPrefixOf' function takes two 'Stream's and returns
--- 'True' iff the first is a prefix of the second.
-isPrefixOf :: (Eq a) => Stream a -> Stream a -> Bool
-isPrefixOf (Stream next1 s1 _) (Stream next2 s2 _) = loop (next1 s1) (next2 s2)
-    where
-      loop Done      _ = True
-      loop _    Done = False
-      loop (Skip s1')     (Skip s2')     = loop (next1 s1') (next2 s2')
-      loop (Skip s1')     x2             = loop (next1 s1') x2
-      loop x1             (Skip s2')     = loop x1          (next2 s2')
-      loop (Yield x1 s1') (Yield x2 s2') = x1 == x2 &&
-                                           loop (next1 s1') (next2 s2')
-{-# INLINE [0] isPrefixOf #-}
-
--- ----------------------------------------------------------------------------
--- * Searching
-
--------------------------------------------------------------------------------
--- ** Searching by equality
-
--- | /O(n)/ elem is the stream membership predicate.
-elem :: Char -> Stream Char -> Bool
-elem w (Stream next s0 _len) = loop_elem s0
-    where
-      loop_elem !s = case next s of
-                       Done -> False
-                       Skip s' -> loop_elem s'
-                       Yield x s' | x == w -> True
-                                  | otherwise -> loop_elem s'
-{-# INLINE [0] elem #-}
-
--------------------------------------------------------------------------------
--- ** Searching with a predicate
-
--- | /O(n)/ The 'findBy' function takes a predicate and a stream,
--- and returns the first element in matching the predicate, or 'Nothing'
--- if there is no such element.
-
-findBy :: (Char -> Bool) -> Stream Char -> Maybe Char
-findBy p (Stream next s0 _len) = loop_find s0
-    where
-      loop_find !s = case next s of
-                       Done -> Nothing
-                       Skip s' -> loop_find s'
-                       Yield x s' | p x -> Just x
-                                  | otherwise -> loop_find s'
-{-# INLINE [0] findBy #-}
-
--- | /O(n)/ Stream index (subscript) operator, starting from 0.
-indexI :: Integral a => Stream Char -> a -> Char
-indexI (Stream next s0 _len) n0
-  | n0 < 0    = streamError "index" "Negative index"
-  | otherwise = loop_index n0 s0
-  where
-    loop_index !n !s = case next s of
-      Done                   -> streamError "index" "Index too large"
-      Skip    s'             -> loop_index  n    s'
-      Yield x s' | n == 0    -> x
-                 | otherwise -> loop_index (n-1) s'
-{-# INLINE [0] indexI #-}
-
--- | /O(n)/ 'filter', applied to a predicate and a stream,
--- returns a stream containing those characters that satisfy the
--- predicate.
-filter :: (Char -> Bool) -> Stream Char -> Stream Char
-filter p (Stream next0 s0 len) = Stream next s0 len -- HINT maybe too high
-  where
-    next !s = case next0 s of
-                Done                   -> Done
-                Skip    s'             -> Skip    s'
-                Yield x s' | p x       -> Yield x s'
-                           | otherwise -> Skip    s'
-{-# INLINE [0] filter #-}
-
-{-# RULES
-  "STREAM filter/filter fusion" forall p q s.
-  filter p (filter q s) = filter (\x -> q x && p x) s
-  #-}
-
--- | The 'findIndexI' function takes a predicate and a stream and
--- returns the index of the first element in the stream satisfying the
--- predicate.
-findIndexI :: Integral a => (Char -> Bool) -> Stream Char -> Maybe a
-findIndexI p s = case findIndicesI p s of
-                  (i:_) -> Just i
-                  _     -> Nothing
-{-# INLINE [0] findIndexI #-}
-
--- | The 'findIndicesI' function takes a predicate and a stream and
--- returns all indices of the elements in the stream satisfying the
--- predicate.
-findIndicesI :: Integral a => (Char -> Bool) -> Stream Char -> [a]
-findIndicesI p (Stream next s0 _len) = loop_findIndex 0 s0
-  where
-    loop_findIndex !i !s = case next s of
-      Done                   -> []
-      Skip    s'             -> loop_findIndex i     s' -- hmm. not caught by QC
-      Yield x s' | p x       -> i : loop_findIndex (i+1) s'
-                 | otherwise -> loop_findIndex (i+1) s'
-{-# INLINE [0] findIndicesI #-}
-
--------------------------------------------------------------------------------
--- * Zipping
-
--- | zipWith generalises 'zip' by zipping with the function given as
--- the first argument, instead of a tupling function.
-zipWith :: (a -> a -> b) -> Stream a -> Stream a -> Stream b
-zipWith f (Stream next0 sa0 len1) (Stream next1 sb0 len2) =
-    Stream next (sa0 :*: sb0 :*: N) (smaller len1 len2)
-    where
-      next (sa :*: sb :*: N) = case next0 sa of
-                                 Done -> Done
-                                 Skip sa' -> Skip (sa' :*: sb :*: N)
-                                 Yield a sa' -> Skip (sa' :*: sb :*: J a)
-
-      next (sa' :*: sb :*: J a) = case next1 sb of
-                                    Done -> Done
-                                    Skip sb' -> Skip (sa' :*: sb' :*: J a)
-                                    Yield b sb' -> Yield (f a b) (sa' :*: sb' :*: N)
-{-# INLINE [0] zipWith #-}
-
--- | /O(n)/ The 'countCharI' function returns the number of times the
--- query element appears in the given stream.
-countCharI :: Integral a => Char -> Stream Char -> a
-countCharI a (Stream next s0 _len) = loop 0 s0
-  where
-    loop !i !s = case next s of
-      Done                   -> i
-      Skip    s'             -> loop i s'
-      Yield x s' | a == x    -> loop (i+1) s'
-                 | otherwise -> loop i s'
-{-# INLINE [0] countCharI #-}
-
-streamError :: String -> String -> a
-streamError func msg = P.error $ "Data.Text.Fusion.Common." ++ func ++ ": " ++ msg
-
-emptyError :: String -> a
-emptyError func = internalError func "Empty input"
-
-internalError :: String -> a
-internalError func = streamError func "Internal error"

Data/Text/Fusion/Internal.hs

-{-# LANGUAGE BangPatterns, ExistentialQuantification #-}
--- |
--- Module      : Data.Text.Fusion.Internal
--- Copyright   : (c) Tom Harper 2008-2009,
---               (c) Bryan O'Sullivan 2009,
---               (c) Duncan Coutts 2009,
---               (c) Jasper Van der Jeugt 2011
---
--- License     : BSD-style
--- Maintainer  : bos@serpentine.com, rtomharper@googlemail.com,
---               duncan@haskell.org
--- Stability   : experimental
--- Portability : GHC
---
--- Core stream fusion functionality for text.
-
-module Data.Text.Fusion.Internal
-    (
-      CC(..)
-    , M(..)
-    , M8
-    , PairS(..)
-    , RS(..)
-    , Step(..)
-    , Stream(..)
-    , Switch(..)
-    , empty
-    ) where
-
-import Data.Text.Fusion.Size
-import Data.Word (Word8)
-
--- | Specialised tuple for case conversion.
-data CC s = CC !s {-# UNPACK #-} !Char {-# UNPACK #-} !Char
-
--- | Specialised, strict Maybe-like type.
-data M a = N
-         | J !a
-
-type M8 = M Word8
-
--- Restreaming state.
-data RS s
-    = RS0 !s
-    | RS1 !s {-# UNPACK #-} !Word8
-    | RS2 !s {-# UNPACK #-} !Word8 {-# UNPACK #-} !Word8
-    | RS3 !s {-# UNPACK #-} !Word8 {-# UNPACK #-} !Word8 {-# UNPACK #-} !Word8
-
-infixl 2 :*:
-data PairS a b = !a :*: !b
-                 -- deriving (Eq, Ord, Show)
-
--- | Allow a function over a stream to switch between two states.
-data Switch = S1 | S2
-
-data Step s a = Done
-              | Skip !s
-              | Yield !a !s
-
-{-
-instance (Show a) => Show (Step s a)
-    where show Done        = "Done"
-          show (Skip _)    = "Skip"
-          show (Yield x _) = "Yield " ++ show x
--}
-
-instance (Eq a) => Eq (Stream a) where
-    (==) = eq
-
-instance (Ord a) => Ord (Stream a) where
-    compare = cmp
-
--- The length hint in a Stream has two roles.  If its value is zero,
--- we trust it, and treat the stream as empty.  Otherwise, we treat it
--- as a hint: it should usually be accurate, so we use it when
--- unstreaming to decide what size array to allocate.  However, the
--- unstreaming functions must be able to cope with the hint being too
--- small or too large.
---
--- The size hint tries to track the UTF-16 code points in a stream,
--- but often counts the number of characters instead.  It can easily
--- undercount if, for instance, a transformed stream contains astral
--- plane characters (those above 0x10000).
-
-data Stream a =
-    forall s. Stream
-    (s -> Step s a)             -- stepper function
-    !s                          -- current state
-    !Size                       -- size hint
-
--- | /O(n)/ Determines if two streams are equal.
-eq :: (Eq a) => Stream a -> Stream a -> Bool
-eq (Stream next1 s1 _) (Stream next2 s2 _) = loop (next1 s1) (next2 s2)
-    where
-      loop Done Done                     = True
-      loop (Skip s1')     (Skip s2')     = loop (next1 s1') (next2 s2')
-      loop (Skip s1')     x2             = loop (next1 s1') x2
-      loop x1             (Skip s2')     = loop x1          (next2 s2')
-      loop Done _                        = False
-      loop _    Done                     = False
-      loop (Yield x1 s1') (Yield x2 s2') = x1 == x2 &&
-                                           loop (next1 s1') (next2 s2')
-{-# INLINE [0] eq #-}
-
-cmp :: (Ord a) => Stream a -> Stream a -> Ordering
-cmp (Stream next1 s1 _) (Stream next2 s2 _) = loop (next1 s1) (next2 s2)
-    where
-      loop Done Done                     = EQ
-      loop (Skip s1')     (Skip s2')     = loop (next1 s1') (next2 s2')
-      loop (Skip s1')     x2             = loop (next1 s1') x2
-      loop x1             (Skip s2')     = loop x1          (next2 s2')
-      loop Done _                        = LT
-      loop _    Done                     = GT
-      loop (Yield x1 s1') (Yield x2 s2') =
-          case compare x1 x2 of
-            EQ    -> loop (next1 s1') (next2 s2')
-            other -> other
-{-# INLINE [0] cmp #-}
-
--- | The empty stream.
-empty :: Stream a
-empty = Stream next () 0
-    where next _ = Done
-{-# INLINE [0] empty #-}

Data/Text/Fusion/Size.hs

-{-# LANGUAGE CPP #-}
-{-# OPTIONS_GHC -fno-warn-missing-methods #-}
--- |
--- Module      : Data.Text.Fusion.Internal
--- Copyright   : (c) Roman Leshchinskiy 2008,
---               (c) Bryan O'Sullivan 2009
---
--- License     : BSD-style
--- Maintainer  : bos@serpentine.com, rtomharper@googlemail.com,
---               duncan@haskell.org
--- Stability   : experimental
--- Portability : portable
---
--- Size hints.
-
-module Data.Text.Fusion.Size
-    (
-      Size
-    , exactly
-    , exactSize
-    , maxSize
-    , unknownSize
-    , smaller
-    , larger
-    , upperBound
-    , isEmpty
-    ) where
-
-#if defined(ASSERTS)
-import Control.Exception (assert)
-#endif
-
-data Size = Exact {-# UNPACK #-} !Int -- ^ Exact size.
-          | Max   {-# UNPACK #-} !Int -- ^ Upper bound on size.
-          | Unknown                   -- ^ Unknown size.
-            deriving (Eq, Show)
-
-exactly :: Size -> Maybe Int
-exactly (Exact n) = Just n
-exactly _         = Nothing
-{-# INLINE exactly #-}
-
-exactSize :: Int -> Size
-exactSize n =
-#if defined(ASSERTS)
-    assert (n >= 0)
-#endif
-    Exact n
-{-# INLINE exactSize #-}
-
-maxSize :: Int -> Size
-maxSize n =
-#if defined(ASSERTS)
-    assert (n >= 0)
-#endif
-    Max n
-{-# INLINE maxSize #-}
-
-unknownSize :: Size
-unknownSize = Unknown
-{-# INLINE unknownSize #-}
-
-instance Num Size where
-    (+) = addSize
-    (-) = subtractSize
-    (*) = mulSize
-
-    fromInteger = f where f = Exact . fromInteger
-                          {-# INLINE f #-}
-
-add :: Int -> Int -> Int
-add m n | mn >=   0 = mn
-        | otherwise = overflowError
-  where mn = m + n
-{-# INLINE add #-}
-
-addSize :: Size -> Size -> Size
-addSize (Exact m) (Exact n) = Exact (add m n)
-addSize (Exact m) (Max   n) = Max   (add m n)
-addSize (Max   m) (Exact n) = Max   (add m n)
-addSize (Max   m) (Max   n) = Max   (add m n)
-addSize _          _       = Unknown
-{-# INLINE addSize #-}
-
-subtractSize :: Size -> Size -> Size
-subtractSize   (Exact m) (Exact n) = Exact (max (m-n) 0)
-subtractSize   (Exact m) (Max   _) = Max   m
-subtractSize   (Max   m) (Exact n) = Max   (max (m-n) 0)
-subtractSize a@(Max   _) (Max   _) = a
-subtractSize a@(Max   _) Unknown   = a
-subtractSize _         _           = Unknown
-{-# INLINE subtractSize #-}
-
-mul :: Int -> Int -> Int
-mul m n
-    | m <= maxBound `quot` n = m * n
-    | otherwise              = overflowError
-{-# INLINE mul #-}
-
-mulSize :: Size -> Size -> Size
-mulSize (Exact m) (Exact n) = Exact (mul m n)
-mulSize (Exact m) (Max   n) = Max   (mul m n)
-mulSize (Max   m) (Exact n) = Max   (mul m n)
-mulSize (Max   m) (Max   n) = Max   (mul m n)
-mulSize _          _        = Unknown
-{-# INLINE mulSize #-}
-
--- | Minimum of two size hints.
-smaller :: Size -> Size -> Size
-smaller   (Exact m) (Exact n) = Exact (m `min` n)
-smaller   (Exact m) (Max   n) = Max   (m `min` n)
-smaller   (Exact m) Unknown   = Max   m
-smaller   (Max   m) (Exact n) = Max   (m `min` n)
-smaller   (Max   m) (Max   n) = Max   (m `min` n)
-smaller a@(Max   _) Unknown   = a
-smaller   Unknown   (Exact n) = Max   n
-smaller   Unknown   (Max   n) = Max   n
-smaller   Unknown   Unknown   = Unknown
-{-# INLINE smaller #-}
-
--- | Maximum of two size hints.
-larger :: Size -> Size -> Size
-larger   (Exact m)   (Exact n)             = Exact (m `max` n)
-larger a@(Exact m) b@(Max   n) | m >= n    = a
-                               | otherwise = b
-larger a@(Max   m) b@(Exact n) | n >= m    = b
-                               | otherwise = a
-larger   (Max   m)   (Max   n)             = Max   (m `max` n)
-larger _             _                     = Unknown
-{-# INLINE larger #-}
-
--- | Compute the maximum size from a size hint, if possible.
-upperBound :: Int -> Size -> Int
-upperBound _ (Exact n) = n
-upperBound _ (Max   n) = n
-upperBound k _         = k
-{-# INLINE upperBound #-}
-
-isEmpty :: Size -> Bool
-isEmpty (Exact n) = n <= 0
-isEmpty (Max   n) = n <= 0
-isEmpty _         = False
-{-# INLINE isEmpty #-}
-
-overflowError :: Int
-overflowError = error "Data.Text.Fusion.Size: size overflow"
 import Control.Monad (liftM2, when)
 import Data.IORef (readIORef, writeIORef)
 import qualified Data.Text as T
-import Data.Text.Fusion (stream)
-import Data.Text.Fusion.Internal (Step(..), Stream(..))
+import Data.Text.Internal.Fusion (stream)
+import Data.Text.Internal.Fusion.Types (Step(..), Stream(..))
 import Data.Text.IO.Internal (hGetLineWith, readChunk)
 import GHC.IO.Buffer (Buffer(..), BufferState(..), CharBufElem, CharBuffer,
                       RawCharBuffer, emptyBuffer, isEmptyBuffer, newCharBuffer,

Data/Text/IO/Internal.hs

 import qualified Control.Exception as E
 import Data.IORef (readIORef, writeIORef)
 import Data.Text (Text)
-import Data.Text.Fusion (unstream)
-import Data.Text.Fusion.Internal (Step(..), Stream(..))
-import Data.Text.Fusion.Size (exactSize, maxSize)
+import Data.Text.Internal.Fusion (unstream)
+import Data.Text.Internal.Fusion.Types (Step(..), Stream(..))
+import Data.Text.Internal.Fusion.Size (exactSize, maxSize)
 import Data.Text.Unsafe (inlinePerformIO)
 import Foreign.Storable (peekElemOff)
 import GHC.IO.Buffer (Buffer(..), CharBuffer, RawCharBuffer, bufferAdjustL,

Data/Text/Internal/Encoding/Fusion.hs

 import Control.Exception (assert)
 #endif
 import Data.ByteString.Internal (ByteString(..), mallocByteString, memcpy)
-import Data.Text.Fusion (Step(..), Stream(..))
-import Data.Text.Fusion.Size