text 0.5 → 0.6
raw patch · 17 files changed
+843/−378 lines, 17 filesdep +deepseqdep ~basedep ~bytestring
Dependencies added: deepseq
Dependency ranges changed: base, bytestring
Files
- Data/Text.hs +59/−26
- Data/Text/Array.hs +5/−6
- Data/Text/Encoding/Fusion.hs +0/−2
- Data/Text/Encoding/Utf16.hs +4/−4
- Data/Text/Encoding/Utf8.hs +18/−18
- Data/Text/Fusion/CaseMapping.hs +226/−226
- Data/Text/Fusion/Common.hs +68/−64
- Data/Text/Fusion/Internal.hs +5/−1
- Data/Text/Lazy.hs +34/−14
- Data/Text/Lazy/Encoding/Fusion.hs +0/−2
- Data/Text/Lazy/Internal.hs +1/−1
- Data/Text/Lazy/Search.hs +0/−1
- scripts/CaseFolding.hs +3/−3
- scripts/SpecialCasing.hs +3/−3
- tests/Benchmarks.hs +400/−0
- tests/Makefile +13/−5
- text.cabal +4/−2
Data/Text.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE BangPatterns, Rank2Types #-} {-# OPTIONS_GHC -fno-warn-orphans #-} -- |@@ -115,6 +115,7 @@ , splitAt , spanBy , break+ , breakEnd , breakBy , group , groupBy@@ -164,10 +165,12 @@ import Prelude (Char, Bool(..), Functor(..), Int, Maybe(..), String, Eq(..), Ord(..), (++), Read(..), Show(..),- (&&), (||), (+), (-), (.), ($),- fromIntegral, div, not, return, otherwise)+ (&&), (||), (+), (-), (.), ($), (>>), (*),+ div, not, return, otherwise)+import Control.DeepSeq (NFData) import Control.Exception (assert) import Data.Char (isSpace)+import Control.Monad (foldM) import Control.Monad.ST (ST) import qualified Data.Text.Array as A import qualified Data.List as L@@ -212,6 +215,8 @@ instance IsString Text where fromString = pack +instance NFData Text+ -- ----------------------------------------------------------------------------- -- * Conversion to/from 'Text' @@ -254,15 +259,10 @@ where len = len1+len2 x = do- arr <- A.unsafeNew len :: ST s (A.MArray s Word16)- copy arr1 off1 (len1+off1) arr 0- copy arr2 off2 (len2+off2) arr len1+ arr <- A.unsafeNew len+ copy arr 0 arr1 off1 len1+ copy arr len1 arr2 off2 (len1+len2) return arr- where- copy arr i top arr' j- | i >= top = return ()- | otherwise = do A.unsafeWrite arr' j (arr `A.unsafeIndex` i)- copy arr (i+1) top arr' (j+1) {-# INLINE append #-} {-# RULES@@ -272,6 +272,14 @@ unstream (S.append (stream t1) (stream t2)) = append t1 t2 #-} +copy :: forall s. A.MArray s Word16 -> Int -> A.Array Word16 -> Int -> Int+ -> ST s ()+copy dest i0 src j0 top = go i0 j0+ where+ go i j | i >= top = return ()+ | otherwise = do A.unsafeWrite dest i (src `A.unsafeIndex` j)+ go (i+1) (j+1)+ -- | /O(1)/ Returns the first character of a 'Text', which must be -- non-empty. Subject to fusion. head :: Text -> Char@@ -386,7 +394,7 @@ -- 'Text's and concatenates the list after interspersing the first -- argument between each element of the list. intercalate :: Text -> [Text] -> Text-intercalate t ts = unstream (S.intercalate (stream t) (L.map stream ts))+intercalate t = concat . (L.intersperse t) {-# INLINE intercalate #-} -- | /O(n)/ The 'intersperse' function takes a character and places it@@ -400,7 +408,7 @@ reverse t = S.reverse (stream t) {-# INLINE reverse #-} --- | /O(m*n)/ Replace every occurrence of one substring with another.+-- | /O(m+n)/ Replace every occurrence of one substring with another. replace :: Text -- ^ Text to search for -> Text -- ^ Replacement text -> Text -- ^ Input text@@ -555,18 +563,21 @@ -- ----------------------------------------------------------------------------- -- ** Special folds --- | /O(n)/ Concatenate a list of 'Text's. Subject to fusion.+-- | /O(n)/ Concatenate a list of 'Text's. concat :: [Text] -> Text-concat ts = unstream (S.concat (L.map stream ts))+concat ts = Text (A.run go) 0 len+ where+ len = L.sum (L.map (\(Text _ _ l) -> l) ts)+ go = do+ arr <- A.unsafeNew len+ let step i (Text a o l) = let j = i + l in copy arr i a o j >> return j+ foldM step 0 ts >> return arr {-# INLINE concat #-} -- | /O(n)/ Map a function over a 'Text' that results in a 'Text', and--- concatenate the results. Subject to fusion.------ Note: if in 'concatMap' @f@ @t@, @f@ is defined in terms of fusible--- functions, it will also be fusible.+-- concatenate the results. concatMap :: (Char -> Text) -> Text -> Text-concatMap f t = unstream (S.concatMap (stream . f) (stream t))+concatMap f = concat . foldr ((:) . f) [] {-# INLINE concatMap #-} -- | /O(n)/ 'any' @p@ @t@ determines whether any character in the@@ -656,11 +667,21 @@ -- ** Generating and unfolding 'Text's -- | /O(n*m)/ 'replicate' @n@ @t@ is a 'Text' consisting of the input--- @t@ repeated @n@ times. Subject to fusion.+-- @t@ repeated @n@ times. replicate :: Int -> Text -> Text-replicate n t- | isSingleton t = replicateChar n (unsafeHead t)- | otherwise = unstream (S.replicateI (fromIntegral n) (S.stream t))+replicate n t@(Text a o l)+ | n <= 0 || l <= 0 = empty+ | n == 1 = t+ | isSingleton t = replicateChar n (unsafeHead t)+ | otherwise = Text (A.run x) 0 len+ where+ len = l * n+ x = do+ arr <- A.unsafeNew len+ let loop !d !i | i >= n = return arr+ | otherwise = let m = d + l+ in copy arr d a o m >> loop m (i+1)+ loop 0 0 {-# INLINE [1] replicate #-} {-# RULES@@ -1020,6 +1041,18 @@ (x:_) -> (textP arr off x, textP arr (off+x) (len-x)) {-# INLINE break #-} +-- | /O(n+m)/ Similar to 'break', but searches from the end of the string.+--+-- The first element of the returned tuple is the prefix of @haystack@+-- up to and including the last match of @needle@. The second is the+-- remainder of @haystack@, following the match.+--+-- > breakEnd "::" "a::b::c" ==> ("a::b::", "c")+breakEnd :: Text -> Text -> (Text, Text)+breakEnd pat src = let (a,b) = break (reverse pat) (reverse src)+ in (reverse b, reverse a)+{-# INLINE breakEnd #-}+ -- | /O(n+m)/ Find all non-overlapping instances of @needle@ in -- @haystack@. The first element of the returned pair is the prefix -- of @haystack@ prior to any matches of @needle@. The second is a@@ -1069,7 +1102,7 @@ -- For example, suppose you have a string that you want to split on -- the substring @\"::\"@, such as @\"foo::bar::quux\"@. Instead of -- searching for the index of @\"::\"@ and taking the substrings--- before and after that index, you would instead use @find "::"@.+-- before and after that index, you would instead use @find \"::\"@. -- | /O(n)/ 'Text' index (subscript) operator, starting from 0. index :: Text -> Int -> Char@@ -1151,6 +1184,7 @@ where (h,t) = spanBy (/= '\n') ps {-# INLINE lines #-} +{- -- | /O(n)/ Portably breaks a 'Text' up into a list of 'Text's at line -- boundaries. --@@ -1158,7 +1192,6 @@ -- return immediately followed by a line feed, or a carriage return. -- This accounts for both Unix and Windows line ending conventions, -- and for the old convention used on Mac OS 9 and earlier.-{- lines' :: Text -> [Text] lines' ps | null ps = [] | otherwise = h : case uncons t of
Data/Text/Array.hs view
@@ -56,10 +56,10 @@ #if defined(__GLASGOW_HASKELL__) #include "MachDeps.h" -import GHC.Base (ByteArray#, MutableByteArray#, Int(..), indexIntArray#,- indexWord16Array#, newByteArray#, readIntArray#,- readWord16Array#, unsafeCoerce#, writeIntArray#,- writeWord16Array#, (+#), (*#))+import GHC.Base (ByteArray#, MutableByteArray#, Int(..),+ indexWord16Array#, newByteArray#,+ readWord16Array#, unsafeCoerce#,+ writeWord16Array#, (*#)) import GHC.Prim (Int#) import GHC.ST (ST(..), runST) import GHC.Word (Word16(..))@@ -78,7 +78,6 @@ import Control.Exception (assert) import Data.Typeable (Typeable1(..), Typeable2(..), TyCon, mkTyCon, mkTyConApp)-import Data.Word (Word16) import Prelude hiding (length, read) #include "Typeable.h"@@ -167,7 +166,7 @@ #if defined(__GLASGOW_HASKELL__) wORD16_SCALE :: Int# -> Int#-wORD16_SCALE n# = scale# *# n# where I# scale# = SIZEOF_WORD16+wORD16_SCALE n# = scale# *# n# where !(I# scale#) = SIZEOF_WORD16 -- | Create an uninitialized mutable array. unsafeNew :: forall s e. Elt e => Int -> ST s (MArray s e)
Data/Text/Encoding/Fusion.hs view
@@ -32,7 +32,6 @@ ) where import Control.Exception (assert)-import Data.ByteString as B import Data.ByteString.Internal (ByteString(..), mallocByteString, memcpy) import Data.Text.Fusion (Step(..), Stream(..)) import Data.Text.Fusion.Size@@ -68,7 +67,6 @@ streamUtf8 onErr bs = Stream next 0 (maxSize l) where l = B.length bs- {-# INLINE next #-} next i | i >= l = Done | U8.validate1 x1 = Yield (unsafeChr8 x1) (i+1)
Data/Text/Encoding/Utf16.hs view
@@ -26,10 +26,10 @@ chr2 :: Word16 -> Word16 -> Char chr2 (W16# a#) (W16# b#) = C# (chr# (upper# +# lower# +# 0x10000#)) where- x# = word2Int# a#- y# = word2Int# b#- upper# = uncheckedIShiftL# (x# -# 0xD800#) 10#- lower# = y# -# 0xDC00#+ !x# = word2Int# a#+ !y# = word2Int# b#+ !upper# = uncheckedIShiftL# (x# -# 0xD800#) 10#+ !lower# = y# -# 0xDC00# {-# INLINE chr2 #-} validate1 :: Word16 -> Bool
Data/Text/Encoding/Utf8.hs view
@@ -73,35 +73,35 @@ chr2 :: Word8 -> Word8 -> Char chr2 (W8# x1#) (W8# x2#) = C# (chr# (z1# +# z2#)) where- y1# = word2Int# x1#- y2# = word2Int# x2#- z1# = uncheckedIShiftL# (y1# -# 0xC0#) 6#- z2# = y2# -# 0x80#+ !y1# = word2Int# x1#+ !y2# = word2Int# x2#+ !z1# = uncheckedIShiftL# (y1# -# 0xC0#) 6#+ !z2# = y2# -# 0x80# {-# INLINE chr2 #-} chr3 :: Word8 -> Word8 -> Word8 -> Char chr3 (W8# x1#) (W8# x2#) (W8# x3#) = C# (chr# (z1# +# z2# +# z3#)) where- y1# = word2Int# x1#- y2# = word2Int# x2#- y3# = word2Int# x3#- z1# = uncheckedIShiftL# (y1# -# 0xE0#) 12#- z2# = uncheckedIShiftL# (y2# -# 0x80#) 6#- z3# = y3# -# 0x80#+ !y1# = word2Int# x1#+ !y2# = word2Int# x2#+ !y3# = word2Int# x3#+ !z1# = uncheckedIShiftL# (y1# -# 0xE0#) 12#+ !z2# = uncheckedIShiftL# (y2# -# 0x80#) 6#+ !z3# = y3# -# 0x80# {-# INLINE chr3 #-} chr4 :: Word8 -> Word8 -> Word8 -> Word8 -> Char chr4 (W8# x1#) (W8# x2#) (W8# x3#) (W8# x4#) = C# (chr# (z1# +# z2# +# z3# +# z4#)) where- y1# = word2Int# x1#- y2# = word2Int# x2#- y3# = word2Int# x3#- y4# = word2Int# x4#- z1# = uncheckedIShiftL# (y1# -# 0xF0#) 18#- z2# = uncheckedIShiftL# (y2# -# 0x80#) 12#- z3# = uncheckedIShiftL# (y3# -# 0x80#) 6#- z4# = y4# -# 0x80#+ !y1# = word2Int# x1#+ !y2# = word2Int# x2#+ !y3# = word2Int# x3#+ !y4# = word2Int# x4#+ !z1# = uncheckedIShiftL# (y1# -# 0xF0#) 18#+ !z2# = uncheckedIShiftL# (y2# -# 0x80#) 12#+ !z3# = uncheckedIShiftL# (y3# -# 0x80#) 6#+ !z4# = y4# -# 0x80# {-# INLINE chr4 #-} validate1 :: Word8 -> Bool
Data/Text/Fusion/CaseMapping.hs view
@@ -5,452 +5,452 @@ import Data.Char import Data.Text.Fusion.Internal -upperMapping :: forall s. Char -> s -> Step (PairS (PairS s Char) Char) Char+upperMapping :: forall s. Char -> s -> Step (CC s) Char {-# INLINE upperMapping #-} -- LATIN SMALL LETTER SHARP S-upperMapping '\x00df' s = Yield '\x0053' (s :*: '\x0053' :*: '\x0000')+upperMapping '\x00df' s = Yield '\x0053' (CC s '\x0053' '\x0000') -- LATIN SMALL LIGATURE FF-upperMapping '\xfb00' s = Yield '\x0046' (s :*: '\x0046' :*: '\x0000')+upperMapping '\xfb00' s = Yield '\x0046' (CC s '\x0046' '\x0000') -- LATIN SMALL LIGATURE FI-upperMapping '\xfb01' s = Yield '\x0046' (s :*: '\x0049' :*: '\x0000')+upperMapping '\xfb01' s = Yield '\x0046' (CC s '\x0049' '\x0000') -- LATIN SMALL LIGATURE FL-upperMapping '\xfb02' s = Yield '\x0046' (s :*: '\x004c' :*: '\x0000')+upperMapping '\xfb02' s = Yield '\x0046' (CC s '\x004c' '\x0000') -- LATIN SMALL LIGATURE FFI-upperMapping '\xfb03' s = Yield '\x0046' (s :*: '\x0046' :*: '\x0049')+upperMapping '\xfb03' s = Yield '\x0046' (CC s '\x0046' '\x0049') -- LATIN SMALL LIGATURE FFL-upperMapping '\xfb04' s = Yield '\x0046' (s :*: '\x0046' :*: '\x004c')+upperMapping '\xfb04' s = Yield '\x0046' (CC s '\x0046' '\x004c') -- LATIN SMALL LIGATURE LONG S T-upperMapping '\xfb05' s = Yield '\x0053' (s :*: '\x0054' :*: '\x0000')+upperMapping '\xfb05' s = Yield '\x0053' (CC s '\x0054' '\x0000') -- LATIN SMALL LIGATURE ST-upperMapping '\xfb06' s = Yield '\x0053' (s :*: '\x0054' :*: '\x0000')+upperMapping '\xfb06' s = Yield '\x0053' (CC s '\x0054' '\x0000') -- ARMENIAN SMALL LIGATURE ECH YIWN-upperMapping '\x0587' s = Yield '\x0535' (s :*: '\x0552' :*: '\x0000')+upperMapping '\x0587' s = Yield '\x0535' (CC s '\x0552' '\x0000') -- ARMENIAN SMALL LIGATURE MEN NOW-upperMapping '\xfb13' s = Yield '\x0544' (s :*: '\x0546' :*: '\x0000')+upperMapping '\xfb13' s = Yield '\x0544' (CC s '\x0546' '\x0000') -- ARMENIAN SMALL LIGATURE MEN ECH-upperMapping '\xfb14' s = Yield '\x0544' (s :*: '\x0535' :*: '\x0000')+upperMapping '\xfb14' s = Yield '\x0544' (CC s '\x0535' '\x0000') -- ARMENIAN SMALL LIGATURE MEN INI-upperMapping '\xfb15' s = Yield '\x0544' (s :*: '\x053b' :*: '\x0000')+upperMapping '\xfb15' s = Yield '\x0544' (CC s '\x053b' '\x0000') -- ARMENIAN SMALL LIGATURE VEW NOW-upperMapping '\xfb16' s = Yield '\x054e' (s :*: '\x0546' :*: '\x0000')+upperMapping '\xfb16' s = Yield '\x054e' (CC s '\x0546' '\x0000') -- ARMENIAN SMALL LIGATURE MEN XEH-upperMapping '\xfb17' s = Yield '\x0544' (s :*: '\x053d' :*: '\x0000')+upperMapping '\xfb17' s = Yield '\x0544' (CC s '\x053d' '\x0000') -- LATIN SMALL LETTER N PRECEDED BY APOSTROPHE-upperMapping '\x0149' s = Yield '\x02bc' (s :*: '\x004e' :*: '\x0000')+upperMapping '\x0149' s = Yield '\x02bc' (CC s '\x004e' '\x0000') -- GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS-upperMapping '\x0390' s = Yield '\x0399' (s :*: '\x0308' :*: '\x0301')+upperMapping '\x0390' s = Yield '\x0399' (CC s '\x0308' '\x0301') -- GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS-upperMapping '\x03b0' s = Yield '\x03a5' (s :*: '\x0308' :*: '\x0301')+upperMapping '\x03b0' s = Yield '\x03a5' (CC s '\x0308' '\x0301') -- LATIN SMALL LETTER J WITH CARON-upperMapping '\x01f0' s = Yield '\x004a' (s :*: '\x030c' :*: '\x0000')+upperMapping '\x01f0' s = Yield '\x004a' (CC s '\x030c' '\x0000') -- LATIN SMALL LETTER H WITH LINE BELOW-upperMapping '\x1e96' s = Yield '\x0048' (s :*: '\x0331' :*: '\x0000')+upperMapping '\x1e96' s = Yield '\x0048' (CC s '\x0331' '\x0000') -- LATIN SMALL LETTER T WITH DIAERESIS-upperMapping '\x1e97' s = Yield '\x0054' (s :*: '\x0308' :*: '\x0000')+upperMapping '\x1e97' s = Yield '\x0054' (CC s '\x0308' '\x0000') -- LATIN SMALL LETTER W WITH RING ABOVE-upperMapping '\x1e98' s = Yield '\x0057' (s :*: '\x030a' :*: '\x0000')+upperMapping '\x1e98' s = Yield '\x0057' (CC s '\x030a' '\x0000') -- LATIN SMALL LETTER Y WITH RING ABOVE-upperMapping '\x1e99' s = Yield '\x0059' (s :*: '\x030a' :*: '\x0000')+upperMapping '\x1e99' s = Yield '\x0059' (CC s '\x030a' '\x0000') -- LATIN SMALL LETTER A WITH RIGHT HALF RING-upperMapping '\x1e9a' s = Yield '\x0041' (s :*: '\x02be' :*: '\x0000')+upperMapping '\x1e9a' s = Yield '\x0041' (CC s '\x02be' '\x0000') -- GREEK SMALL LETTER UPSILON WITH PSILI-upperMapping '\x1f50' s = Yield '\x03a5' (s :*: '\x0313' :*: '\x0000')+upperMapping '\x1f50' s = Yield '\x03a5' (CC s '\x0313' '\x0000') -- GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA-upperMapping '\x1f52' s = Yield '\x03a5' (s :*: '\x0313' :*: '\x0300')+upperMapping '\x1f52' s = Yield '\x03a5' (CC s '\x0313' '\x0300') -- GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA-upperMapping '\x1f54' s = Yield '\x03a5' (s :*: '\x0313' :*: '\x0301')+upperMapping '\x1f54' s = Yield '\x03a5' (CC s '\x0313' '\x0301') -- GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI-upperMapping '\x1f56' s = Yield '\x03a5' (s :*: '\x0313' :*: '\x0342')+upperMapping '\x1f56' s = Yield '\x03a5' (CC s '\x0313' '\x0342') -- GREEK SMALL LETTER ALPHA WITH PERISPOMENI-upperMapping '\x1fb6' s = Yield '\x0391' (s :*: '\x0342' :*: '\x0000')+upperMapping '\x1fb6' s = Yield '\x0391' (CC s '\x0342' '\x0000') -- GREEK SMALL LETTER ETA WITH PERISPOMENI-upperMapping '\x1fc6' s = Yield '\x0397' (s :*: '\x0342' :*: '\x0000')+upperMapping '\x1fc6' s = Yield '\x0397' (CC s '\x0342' '\x0000') -- GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA-upperMapping '\x1fd2' s = Yield '\x0399' (s :*: '\x0308' :*: '\x0300')+upperMapping '\x1fd2' s = Yield '\x0399' (CC s '\x0308' '\x0300') -- GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA-upperMapping '\x1fd3' s = Yield '\x0399' (s :*: '\x0308' :*: '\x0301')+upperMapping '\x1fd3' s = Yield '\x0399' (CC s '\x0308' '\x0301') -- GREEK SMALL LETTER IOTA WITH PERISPOMENI-upperMapping '\x1fd6' s = Yield '\x0399' (s :*: '\x0342' :*: '\x0000')+upperMapping '\x1fd6' s = Yield '\x0399' (CC s '\x0342' '\x0000') -- GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI-upperMapping '\x1fd7' s = Yield '\x0399' (s :*: '\x0308' :*: '\x0342')+upperMapping '\x1fd7' s = Yield '\x0399' (CC s '\x0308' '\x0342') -- GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA-upperMapping '\x1fe2' s = Yield '\x03a5' (s :*: '\x0308' :*: '\x0300')+upperMapping '\x1fe2' s = Yield '\x03a5' (CC s '\x0308' '\x0300') -- GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA-upperMapping '\x1fe3' s = Yield '\x03a5' (s :*: '\x0308' :*: '\x0301')+upperMapping '\x1fe3' s = Yield '\x03a5' (CC s '\x0308' '\x0301') -- GREEK SMALL LETTER RHO WITH PSILI-upperMapping '\x1fe4' s = Yield '\x03a1' (s :*: '\x0313' :*: '\x0000')+upperMapping '\x1fe4' s = Yield '\x03a1' (CC s '\x0313' '\x0000') -- GREEK SMALL LETTER UPSILON WITH PERISPOMENI-upperMapping '\x1fe6' s = Yield '\x03a5' (s :*: '\x0342' :*: '\x0000')+upperMapping '\x1fe6' s = Yield '\x03a5' (CC s '\x0342' '\x0000') -- GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI-upperMapping '\x1fe7' s = Yield '\x03a5' (s :*: '\x0308' :*: '\x0342')+upperMapping '\x1fe7' s = Yield '\x03a5' (CC s '\x0308' '\x0342') -- GREEK SMALL LETTER OMEGA WITH PERISPOMENI-upperMapping '\x1ff6' s = Yield '\x03a9' (s :*: '\x0342' :*: '\x0000')+upperMapping '\x1ff6' s = Yield '\x03a9' (CC s '\x0342' '\x0000') -- GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI-upperMapping '\x1f80' s = Yield '\x1f08' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1f80' s = Yield '\x1f08' (CC s '\x0399' '\x0000') -- GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI-upperMapping '\x1f81' s = Yield '\x1f09' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1f81' s = Yield '\x1f09' (CC s '\x0399' '\x0000') -- GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI-upperMapping '\x1f82' s = Yield '\x1f0a' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1f82' s = Yield '\x1f0a' (CC s '\x0399' '\x0000') -- GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI-upperMapping '\x1f83' s = Yield '\x1f0b' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1f83' s = Yield '\x1f0b' (CC s '\x0399' '\x0000') -- GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI-upperMapping '\x1f84' s = Yield '\x1f0c' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1f84' s = Yield '\x1f0c' (CC s '\x0399' '\x0000') -- GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI-upperMapping '\x1f85' s = Yield '\x1f0d' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1f85' s = Yield '\x1f0d' (CC s '\x0399' '\x0000') -- GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI-upperMapping '\x1f86' s = Yield '\x1f0e' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1f86' s = Yield '\x1f0e' (CC s '\x0399' '\x0000') -- GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI-upperMapping '\x1f87' s = Yield '\x1f0f' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1f87' s = Yield '\x1f0f' (CC s '\x0399' '\x0000') -- GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI-upperMapping '\x1f88' s = Yield '\x1f08' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1f88' s = Yield '\x1f08' (CC s '\x0399' '\x0000') -- GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI-upperMapping '\x1f89' s = Yield '\x1f09' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1f89' s = Yield '\x1f09' (CC s '\x0399' '\x0000') -- GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI-upperMapping '\x1f8a' s = Yield '\x1f0a' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1f8a' s = Yield '\x1f0a' (CC s '\x0399' '\x0000') -- GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI-upperMapping '\x1f8b' s = Yield '\x1f0b' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1f8b' s = Yield '\x1f0b' (CC s '\x0399' '\x0000') -- GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI-upperMapping '\x1f8c' s = Yield '\x1f0c' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1f8c' s = Yield '\x1f0c' (CC s '\x0399' '\x0000') -- GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI-upperMapping '\x1f8d' s = Yield '\x1f0d' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1f8d' s = Yield '\x1f0d' (CC s '\x0399' '\x0000') -- GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI-upperMapping '\x1f8e' s = Yield '\x1f0e' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1f8e' s = Yield '\x1f0e' (CC s '\x0399' '\x0000') -- GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI-upperMapping '\x1f8f' s = Yield '\x1f0f' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1f8f' s = Yield '\x1f0f' (CC s '\x0399' '\x0000') -- GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI-upperMapping '\x1f90' s = Yield '\x1f28' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1f90' s = Yield '\x1f28' (CC s '\x0399' '\x0000') -- GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI-upperMapping '\x1f91' s = Yield '\x1f29' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1f91' s = Yield '\x1f29' (CC s '\x0399' '\x0000') -- GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI-upperMapping '\x1f92' s = Yield '\x1f2a' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1f92' s = Yield '\x1f2a' (CC s '\x0399' '\x0000') -- GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI-upperMapping '\x1f93' s = Yield '\x1f2b' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1f93' s = Yield '\x1f2b' (CC s '\x0399' '\x0000') -- GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI-upperMapping '\x1f94' s = Yield '\x1f2c' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1f94' s = Yield '\x1f2c' (CC s '\x0399' '\x0000') -- GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI-upperMapping '\x1f95' s = Yield '\x1f2d' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1f95' s = Yield '\x1f2d' (CC s '\x0399' '\x0000') -- GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI-upperMapping '\x1f96' s = Yield '\x1f2e' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1f96' s = Yield '\x1f2e' (CC s '\x0399' '\x0000') -- GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI-upperMapping '\x1f97' s = Yield '\x1f2f' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1f97' s = Yield '\x1f2f' (CC s '\x0399' '\x0000') -- GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI-upperMapping '\x1f98' s = Yield '\x1f28' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1f98' s = Yield '\x1f28' (CC s '\x0399' '\x0000') -- GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI-upperMapping '\x1f99' s = Yield '\x1f29' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1f99' s = Yield '\x1f29' (CC s '\x0399' '\x0000') -- GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI-upperMapping '\x1f9a' s = Yield '\x1f2a' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1f9a' s = Yield '\x1f2a' (CC s '\x0399' '\x0000') -- GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI-upperMapping '\x1f9b' s = Yield '\x1f2b' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1f9b' s = Yield '\x1f2b' (CC s '\x0399' '\x0000') -- GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI-upperMapping '\x1f9c' s = Yield '\x1f2c' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1f9c' s = Yield '\x1f2c' (CC s '\x0399' '\x0000') -- GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI-upperMapping '\x1f9d' s = Yield '\x1f2d' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1f9d' s = Yield '\x1f2d' (CC s '\x0399' '\x0000') -- GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI-upperMapping '\x1f9e' s = Yield '\x1f2e' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1f9e' s = Yield '\x1f2e' (CC s '\x0399' '\x0000') -- GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI-upperMapping '\x1f9f' s = Yield '\x1f2f' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1f9f' s = Yield '\x1f2f' (CC s '\x0399' '\x0000') -- GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI-upperMapping '\x1fa0' s = Yield '\x1f68' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1fa0' s = Yield '\x1f68' (CC s '\x0399' '\x0000') -- GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI-upperMapping '\x1fa1' s = Yield '\x1f69' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1fa1' s = Yield '\x1f69' (CC s '\x0399' '\x0000') -- GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI-upperMapping '\x1fa2' s = Yield '\x1f6a' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1fa2' s = Yield '\x1f6a' (CC s '\x0399' '\x0000') -- GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI-upperMapping '\x1fa3' s = Yield '\x1f6b' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1fa3' s = Yield '\x1f6b' (CC s '\x0399' '\x0000') -- GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI-upperMapping '\x1fa4' s = Yield '\x1f6c' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1fa4' s = Yield '\x1f6c' (CC s '\x0399' '\x0000') -- GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI-upperMapping '\x1fa5' s = Yield '\x1f6d' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1fa5' s = Yield '\x1f6d' (CC s '\x0399' '\x0000') -- GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI-upperMapping '\x1fa6' s = Yield '\x1f6e' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1fa6' s = Yield '\x1f6e' (CC s '\x0399' '\x0000') -- GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI-upperMapping '\x1fa7' s = Yield '\x1f6f' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1fa7' s = Yield '\x1f6f' (CC s '\x0399' '\x0000') -- GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI-upperMapping '\x1fa8' s = Yield '\x1f68' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1fa8' s = Yield '\x1f68' (CC s '\x0399' '\x0000') -- GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI-upperMapping '\x1fa9' s = Yield '\x1f69' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1fa9' s = Yield '\x1f69' (CC s '\x0399' '\x0000') -- GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI-upperMapping '\x1faa' s = Yield '\x1f6a' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1faa' s = Yield '\x1f6a' (CC s '\x0399' '\x0000') -- GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI-upperMapping '\x1fab' s = Yield '\x1f6b' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1fab' s = Yield '\x1f6b' (CC s '\x0399' '\x0000') -- GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI-upperMapping '\x1fac' s = Yield '\x1f6c' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1fac' s = Yield '\x1f6c' (CC s '\x0399' '\x0000') -- GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI-upperMapping '\x1fad' s = Yield '\x1f6d' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1fad' s = Yield '\x1f6d' (CC s '\x0399' '\x0000') -- GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI-upperMapping '\x1fae' s = Yield '\x1f6e' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1fae' s = Yield '\x1f6e' (CC s '\x0399' '\x0000') -- GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI-upperMapping '\x1faf' s = Yield '\x1f6f' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1faf' s = Yield '\x1f6f' (CC s '\x0399' '\x0000') -- GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI-upperMapping '\x1fb3' s = Yield '\x0391' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1fb3' s = Yield '\x0391' (CC s '\x0399' '\x0000') -- GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI-upperMapping '\x1fbc' s = Yield '\x0391' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1fbc' s = Yield '\x0391' (CC s '\x0399' '\x0000') -- GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI-upperMapping '\x1fc3' s = Yield '\x0397' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1fc3' s = Yield '\x0397' (CC s '\x0399' '\x0000') -- GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI-upperMapping '\x1fcc' s = Yield '\x0397' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1fcc' s = Yield '\x0397' (CC s '\x0399' '\x0000') -- GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI-upperMapping '\x1ff3' s = Yield '\x03a9' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1ff3' s = Yield '\x03a9' (CC s '\x0399' '\x0000') -- GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI-upperMapping '\x1ffc' s = Yield '\x03a9' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1ffc' s = Yield '\x03a9' (CC s '\x0399' '\x0000') -- GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI-upperMapping '\x1fb2' s = Yield '\x1fba' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1fb2' s = Yield '\x1fba' (CC s '\x0399' '\x0000') -- GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI-upperMapping '\x1fb4' s = Yield '\x0386' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1fb4' s = Yield '\x0386' (CC s '\x0399' '\x0000') -- GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI-upperMapping '\x1fc2' s = Yield '\x1fca' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1fc2' s = Yield '\x1fca' (CC s '\x0399' '\x0000') -- GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI-upperMapping '\x1fc4' s = Yield '\x0389' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1fc4' s = Yield '\x0389' (CC s '\x0399' '\x0000') -- GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI-upperMapping '\x1ff2' s = Yield '\x1ffa' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1ff2' s = Yield '\x1ffa' (CC s '\x0399' '\x0000') -- GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI-upperMapping '\x1ff4' s = Yield '\x038f' (s :*: '\x0399' :*: '\x0000')+upperMapping '\x1ff4' s = Yield '\x038f' (CC s '\x0399' '\x0000') -- GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI-upperMapping '\x1fb7' s = Yield '\x0391' (s :*: '\x0342' :*: '\x0399')+upperMapping '\x1fb7' s = Yield '\x0391' (CC s '\x0342' '\x0399') -- GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI-upperMapping '\x1fc7' s = Yield '\x0397' (s :*: '\x0342' :*: '\x0399')+upperMapping '\x1fc7' s = Yield '\x0397' (CC s '\x0342' '\x0399') -- GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI-upperMapping '\x1ff7' s = Yield '\x03a9' (s :*: '\x0342' :*: '\x0399')-upperMapping c s = Yield (toUpper c) (s :*: '\0' :*: '\0')-lowerMapping :: forall s. Char -> s -> Step (PairS (PairS s Char) Char) Char+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' (s :*: '\x0307' :*: '\x0000')-lowerMapping c s = Yield (toLower c) (s :*: '\0' :*: '\0')-foldMapping :: forall s. Char -> s -> Step (PairS (PairS s Char) Char) Char+lowerMapping '\x0130' s = Yield '\x0069' (CC s '\x0307' '\x0000')+lowerMapping c s = Yield (toLower c) (CC s '\0' '\0')+foldMapping :: forall s. Char -> s -> Step (CC s) Char {-# INLINE foldMapping #-} -- MICRO SIGN-foldMapping '\x00b5' s = Yield '\x03bc' (s :*: '\x0000' :*: '\x0000')+foldMapping '\x00b5' s = Yield '\x03bc' (CC s '\x0000' '\x0000') -- LATIN SMALL LETTER SHARP S-foldMapping '\x00df' s = Yield '\x0073' (s :*: '\x0073' :*: '\x0000')+foldMapping '\x00df' s = Yield '\x0073' (CC s '\x0073' '\x0000') -- LATIN CAPITAL LETTER I WITH DOT ABOVE-foldMapping '\x0130' s = Yield '\x0069' (s :*: '\x0307' :*: '\x0000')+foldMapping '\x0130' s = Yield '\x0069' (CC s '\x0307' '\x0000') -- LATIN SMALL LETTER N PRECEDED BY APOSTROPHE-foldMapping '\x0149' s = Yield '\x02bc' (s :*: '\x006e' :*: '\x0000')+foldMapping '\x0149' s = Yield '\x02bc' (CC s '\x006e' '\x0000') -- LATIN SMALL LETTER LONG S-foldMapping '\x017f' s = Yield '\x0073' (s :*: '\x0000' :*: '\x0000')+foldMapping '\x017f' s = Yield '\x0073' (CC s '\x0000' '\x0000') -- LATIN SMALL LETTER J WITH CARON-foldMapping '\x01f0' s = Yield '\x006a' (s :*: '\x030c' :*: '\x0000')+foldMapping '\x01f0' s = Yield '\x006a' (CC s '\x030c' '\x0000') -- COMBINING GREEK YPOGEGRAMMENI-foldMapping '\x0345' s = Yield '\x03b9' (s :*: '\x0000' :*: '\x0000')+foldMapping '\x0345' s = Yield '\x03b9' (CC s '\x0000' '\x0000') -- GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS-foldMapping '\x0390' s = Yield '\x03b9' (s :*: '\x0308' :*: '\x0301')+foldMapping '\x0390' s = Yield '\x03b9' (CC s '\x0308' '\x0301') -- GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS-foldMapping '\x03b0' s = Yield '\x03c5' (s :*: '\x0308' :*: '\x0301')+foldMapping '\x03b0' s = Yield '\x03c5' (CC s '\x0308' '\x0301') -- GREEK SMALL LETTER FINAL SIGMA-foldMapping '\x03c2' s = Yield '\x03c3' (s :*: '\x0000' :*: '\x0000')+foldMapping '\x03c2' s = Yield '\x03c3' (CC s '\x0000' '\x0000') -- GREEK BETA SYMBOL-foldMapping '\x03d0' s = Yield '\x03b2' (s :*: '\x0000' :*: '\x0000')+foldMapping '\x03d0' s = Yield '\x03b2' (CC s '\x0000' '\x0000') -- GREEK THETA SYMBOL-foldMapping '\x03d1' s = Yield '\x03b8' (s :*: '\x0000' :*: '\x0000')+foldMapping '\x03d1' s = Yield '\x03b8' (CC s '\x0000' '\x0000') -- GREEK PHI SYMBOL-foldMapping '\x03d5' s = Yield '\x03c6' (s :*: '\x0000' :*: '\x0000')+foldMapping '\x03d5' s = Yield '\x03c6' (CC s '\x0000' '\x0000') -- GREEK PI SYMBOL-foldMapping '\x03d6' s = Yield '\x03c0' (s :*: '\x0000' :*: '\x0000')+foldMapping '\x03d6' s = Yield '\x03c0' (CC s '\x0000' '\x0000') -- GREEK KAPPA SYMBOL-foldMapping '\x03f0' s = Yield '\x03ba' (s :*: '\x0000' :*: '\x0000')+foldMapping '\x03f0' s = Yield '\x03ba' (CC s '\x0000' '\x0000') -- GREEK RHO SYMBOL-foldMapping '\x03f1' s = Yield '\x03c1' (s :*: '\x0000' :*: '\x0000')+foldMapping '\x03f1' s = Yield '\x03c1' (CC s '\x0000' '\x0000') -- GREEK LUNATE EPSILON SYMBOL-foldMapping '\x03f5' s = Yield '\x03b5' (s :*: '\x0000' :*: '\x0000')+foldMapping '\x03f5' s = Yield '\x03b5' (CC s '\x0000' '\x0000') -- ARMENIAN SMALL LIGATURE ECH YIWN-foldMapping '\x0587' s = Yield '\x0565' (s :*: '\x0582' :*: '\x0000')+foldMapping '\x0587' s = Yield '\x0565' (CC s '\x0582' '\x0000') -- LATIN SMALL LETTER H WITH LINE BELOW-foldMapping '\x1e96' s = Yield '\x0068' (s :*: '\x0331' :*: '\x0000')+foldMapping '\x1e96' s = Yield '\x0068' (CC s '\x0331' '\x0000') -- LATIN SMALL LETTER T WITH DIAERESIS-foldMapping '\x1e97' s = Yield '\x0074' (s :*: '\x0308' :*: '\x0000')+foldMapping '\x1e97' s = Yield '\x0074' (CC s '\x0308' '\x0000') -- LATIN SMALL LETTER W WITH RING ABOVE-foldMapping '\x1e98' s = Yield '\x0077' (s :*: '\x030a' :*: '\x0000')+foldMapping '\x1e98' s = Yield '\x0077' (CC s '\x030a' '\x0000') -- LATIN SMALL LETTER Y WITH RING ABOVE-foldMapping '\x1e99' s = Yield '\x0079' (s :*: '\x030a' :*: '\x0000')+foldMapping '\x1e99' s = Yield '\x0079' (CC s '\x030a' '\x0000') -- LATIN SMALL LETTER A WITH RIGHT HALF RING-foldMapping '\x1e9a' s = Yield '\x0061' (s :*: '\x02be' :*: '\x0000')+foldMapping '\x1e9a' s = Yield '\x0061' (CC s '\x02be' '\x0000') -- LATIN SMALL LETTER LONG S WITH DOT ABOVE-foldMapping '\x1e9b' s = Yield '\x1e61' (s :*: '\x0000' :*: '\x0000')+foldMapping '\x1e9b' s = Yield '\x1e61' (CC s '\x0000' '\x0000') -- LATIN CAPITAL LETTER SHARP S-foldMapping '\x1e9e' s = Yield '\x0073' (s :*: '\x0073' :*: '\x0000')+foldMapping '\x1e9e' s = Yield '\x0073' (CC s '\x0073' '\x0000') -- GREEK SMALL LETTER UPSILON WITH PSILI-foldMapping '\x1f50' s = Yield '\x03c5' (s :*: '\x0313' :*: '\x0000')+foldMapping '\x1f50' s = Yield '\x03c5' (CC s '\x0313' '\x0000') -- GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA-foldMapping '\x1f52' s = Yield '\x03c5' (s :*: '\x0313' :*: '\x0300')+foldMapping '\x1f52' s = Yield '\x03c5' (CC s '\x0313' '\x0300') -- GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA-foldMapping '\x1f54' s = Yield '\x03c5' (s :*: '\x0313' :*: '\x0301')+foldMapping '\x1f54' s = Yield '\x03c5' (CC s '\x0313' '\x0301') -- GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI-foldMapping '\x1f56' s = Yield '\x03c5' (s :*: '\x0313' :*: '\x0342')+foldMapping '\x1f56' s = Yield '\x03c5' (CC s '\x0313' '\x0342') -- GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI-foldMapping '\x1f80' s = Yield '\x1f00' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1f80' s = Yield '\x1f00' (CC s '\x03b9' '\x0000') -- GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI-foldMapping '\x1f81' s = Yield '\x1f01' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1f81' s = Yield '\x1f01' (CC s '\x03b9' '\x0000') -- GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI-foldMapping '\x1f82' s = Yield '\x1f02' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1f82' s = Yield '\x1f02' (CC s '\x03b9' '\x0000') -- GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI-foldMapping '\x1f83' s = Yield '\x1f03' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1f83' s = Yield '\x1f03' (CC s '\x03b9' '\x0000') -- GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI-foldMapping '\x1f84' s = Yield '\x1f04' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1f84' s = Yield '\x1f04' (CC s '\x03b9' '\x0000') -- GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI-foldMapping '\x1f85' s = Yield '\x1f05' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1f85' s = Yield '\x1f05' (CC s '\x03b9' '\x0000') -- GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI-foldMapping '\x1f86' s = Yield '\x1f06' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1f86' s = Yield '\x1f06' (CC s '\x03b9' '\x0000') -- GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI-foldMapping '\x1f87' s = Yield '\x1f07' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1f87' s = Yield '\x1f07' (CC s '\x03b9' '\x0000') -- GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI-foldMapping '\x1f88' s = Yield '\x1f00' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1f88' s = Yield '\x1f00' (CC s '\x03b9' '\x0000') -- GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI-foldMapping '\x1f89' s = Yield '\x1f01' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1f89' s = Yield '\x1f01' (CC s '\x03b9' '\x0000') -- GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI-foldMapping '\x1f8a' s = Yield '\x1f02' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1f8a' s = Yield '\x1f02' (CC s '\x03b9' '\x0000') -- GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI-foldMapping '\x1f8b' s = Yield '\x1f03' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1f8b' s = Yield '\x1f03' (CC s '\x03b9' '\x0000') -- GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI-foldMapping '\x1f8c' s = Yield '\x1f04' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1f8c' s = Yield '\x1f04' (CC s '\x03b9' '\x0000') -- GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI-foldMapping '\x1f8d' s = Yield '\x1f05' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1f8d' s = Yield '\x1f05' (CC s '\x03b9' '\x0000') -- GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI-foldMapping '\x1f8e' s = Yield '\x1f06' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1f8e' s = Yield '\x1f06' (CC s '\x03b9' '\x0000') -- GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI-foldMapping '\x1f8f' s = Yield '\x1f07' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1f8f' s = Yield '\x1f07' (CC s '\x03b9' '\x0000') -- GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI-foldMapping '\x1f90' s = Yield '\x1f20' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1f90' s = Yield '\x1f20' (CC s '\x03b9' '\x0000') -- GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI-foldMapping '\x1f91' s = Yield '\x1f21' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1f91' s = Yield '\x1f21' (CC s '\x03b9' '\x0000') -- GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI-foldMapping '\x1f92' s = Yield '\x1f22' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1f92' s = Yield '\x1f22' (CC s '\x03b9' '\x0000') -- GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI-foldMapping '\x1f93' s = Yield '\x1f23' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1f93' s = Yield '\x1f23' (CC s '\x03b9' '\x0000') -- GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI-foldMapping '\x1f94' s = Yield '\x1f24' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1f94' s = Yield '\x1f24' (CC s '\x03b9' '\x0000') -- GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI-foldMapping '\x1f95' s = Yield '\x1f25' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1f95' s = Yield '\x1f25' (CC s '\x03b9' '\x0000') -- GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI-foldMapping '\x1f96' s = Yield '\x1f26' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1f96' s = Yield '\x1f26' (CC s '\x03b9' '\x0000') -- GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI-foldMapping '\x1f97' s = Yield '\x1f27' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1f97' s = Yield '\x1f27' (CC s '\x03b9' '\x0000') -- GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI-foldMapping '\x1f98' s = Yield '\x1f20' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1f98' s = Yield '\x1f20' (CC s '\x03b9' '\x0000') -- GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI-foldMapping '\x1f99' s = Yield '\x1f21' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1f99' s = Yield '\x1f21' (CC s '\x03b9' '\x0000') -- GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI-foldMapping '\x1f9a' s = Yield '\x1f22' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1f9a' s = Yield '\x1f22' (CC s '\x03b9' '\x0000') -- GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI-foldMapping '\x1f9b' s = Yield '\x1f23' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1f9b' s = Yield '\x1f23' (CC s '\x03b9' '\x0000') -- GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI-foldMapping '\x1f9c' s = Yield '\x1f24' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1f9c' s = Yield '\x1f24' (CC s '\x03b9' '\x0000') -- GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI-foldMapping '\x1f9d' s = Yield '\x1f25' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1f9d' s = Yield '\x1f25' (CC s '\x03b9' '\x0000') -- GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI-foldMapping '\x1f9e' s = Yield '\x1f26' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1f9e' s = Yield '\x1f26' (CC s '\x03b9' '\x0000') -- GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI-foldMapping '\x1f9f' s = Yield '\x1f27' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1f9f' s = Yield '\x1f27' (CC s '\x03b9' '\x0000') -- GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI-foldMapping '\x1fa0' s = Yield '\x1f60' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1fa0' s = Yield '\x1f60' (CC s '\x03b9' '\x0000') -- GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI-foldMapping '\x1fa1' s = Yield '\x1f61' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1fa1' s = Yield '\x1f61' (CC s '\x03b9' '\x0000') -- GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI-foldMapping '\x1fa2' s = Yield '\x1f62' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1fa2' s = Yield '\x1f62' (CC s '\x03b9' '\x0000') -- GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI-foldMapping '\x1fa3' s = Yield '\x1f63' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1fa3' s = Yield '\x1f63' (CC s '\x03b9' '\x0000') -- GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI-foldMapping '\x1fa4' s = Yield '\x1f64' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1fa4' s = Yield '\x1f64' (CC s '\x03b9' '\x0000') -- GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI-foldMapping '\x1fa5' s = Yield '\x1f65' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1fa5' s = Yield '\x1f65' (CC s '\x03b9' '\x0000') -- GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI-foldMapping '\x1fa6' s = Yield '\x1f66' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1fa6' s = Yield '\x1f66' (CC s '\x03b9' '\x0000') -- GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI-foldMapping '\x1fa7' s = Yield '\x1f67' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1fa7' s = Yield '\x1f67' (CC s '\x03b9' '\x0000') -- GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI-foldMapping '\x1fa8' s = Yield '\x1f60' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1fa8' s = Yield '\x1f60' (CC s '\x03b9' '\x0000') -- GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI-foldMapping '\x1fa9' s = Yield '\x1f61' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1fa9' s = Yield '\x1f61' (CC s '\x03b9' '\x0000') -- GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI-foldMapping '\x1faa' s = Yield '\x1f62' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1faa' s = Yield '\x1f62' (CC s '\x03b9' '\x0000') -- GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI-foldMapping '\x1fab' s = Yield '\x1f63' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1fab' s = Yield '\x1f63' (CC s '\x03b9' '\x0000') -- GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI-foldMapping '\x1fac' s = Yield '\x1f64' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1fac' s = Yield '\x1f64' (CC s '\x03b9' '\x0000') -- GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI-foldMapping '\x1fad' s = Yield '\x1f65' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1fad' s = Yield '\x1f65' (CC s '\x03b9' '\x0000') -- GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI-foldMapping '\x1fae' s = Yield '\x1f66' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1fae' s = Yield '\x1f66' (CC s '\x03b9' '\x0000') -- GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI-foldMapping '\x1faf' s = Yield '\x1f67' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1faf' s = Yield '\x1f67' (CC s '\x03b9' '\x0000') -- GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI-foldMapping '\x1fb2' s = Yield '\x1f70' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1fb2' s = Yield '\x1f70' (CC s '\x03b9' '\x0000') -- GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI-foldMapping '\x1fb3' s = Yield '\x03b1' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1fb3' s = Yield '\x03b1' (CC s '\x03b9' '\x0000') -- GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI-foldMapping '\x1fb4' s = Yield '\x03ac' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1fb4' s = Yield '\x03ac' (CC s '\x03b9' '\x0000') -- GREEK SMALL LETTER ALPHA WITH PERISPOMENI-foldMapping '\x1fb6' s = Yield '\x03b1' (s :*: '\x0342' :*: '\x0000')+foldMapping '\x1fb6' s = Yield '\x03b1' (CC s '\x0342' '\x0000') -- GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI-foldMapping '\x1fb7' s = Yield '\x03b1' (s :*: '\x0342' :*: '\x03b9')+foldMapping '\x1fb7' s = Yield '\x03b1' (CC s '\x0342' '\x03b9') -- GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI-foldMapping '\x1fbc' s = Yield '\x03b1' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1fbc' s = Yield '\x03b1' (CC s '\x03b9' '\x0000') -- GREEK PROSGEGRAMMENI-foldMapping '\x1fbe' s = Yield '\x03b9' (s :*: '\x0000' :*: '\x0000')+foldMapping '\x1fbe' s = Yield '\x03b9' (CC s '\x0000' '\x0000') -- GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI-foldMapping '\x1fc2' s = Yield '\x1f74' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1fc2' s = Yield '\x1f74' (CC s '\x03b9' '\x0000') -- GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI-foldMapping '\x1fc3' s = Yield '\x03b7' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1fc3' s = Yield '\x03b7' (CC s '\x03b9' '\x0000') -- GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI-foldMapping '\x1fc4' s = Yield '\x03ae' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1fc4' s = Yield '\x03ae' (CC s '\x03b9' '\x0000') -- GREEK SMALL LETTER ETA WITH PERISPOMENI-foldMapping '\x1fc6' s = Yield '\x03b7' (s :*: '\x0342' :*: '\x0000')+foldMapping '\x1fc6' s = Yield '\x03b7' (CC s '\x0342' '\x0000') -- GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI-foldMapping '\x1fc7' s = Yield '\x03b7' (s :*: '\x0342' :*: '\x03b9')+foldMapping '\x1fc7' s = Yield '\x03b7' (CC s '\x0342' '\x03b9') -- GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI-foldMapping '\x1fcc' s = Yield '\x03b7' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1fcc' s = Yield '\x03b7' (CC s '\x03b9' '\x0000') -- GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA-foldMapping '\x1fd2' s = Yield '\x03b9' (s :*: '\x0308' :*: '\x0300')+foldMapping '\x1fd2' s = Yield '\x03b9' (CC s '\x0308' '\x0300') -- GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA-foldMapping '\x1fd3' s = Yield '\x03b9' (s :*: '\x0308' :*: '\x0301')+foldMapping '\x1fd3' s = Yield '\x03b9' (CC s '\x0308' '\x0301') -- GREEK SMALL LETTER IOTA WITH PERISPOMENI-foldMapping '\x1fd6' s = Yield '\x03b9' (s :*: '\x0342' :*: '\x0000')+foldMapping '\x1fd6' s = Yield '\x03b9' (CC s '\x0342' '\x0000') -- GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI-foldMapping '\x1fd7' s = Yield '\x03b9' (s :*: '\x0308' :*: '\x0342')+foldMapping '\x1fd7' s = Yield '\x03b9' (CC s '\x0308' '\x0342') -- GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA-foldMapping '\x1fe2' s = Yield '\x03c5' (s :*: '\x0308' :*: '\x0300')+foldMapping '\x1fe2' s = Yield '\x03c5' (CC s '\x0308' '\x0300') -- GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA-foldMapping '\x1fe3' s = Yield '\x03c5' (s :*: '\x0308' :*: '\x0301')+foldMapping '\x1fe3' s = Yield '\x03c5' (CC s '\x0308' '\x0301') -- GREEK SMALL LETTER RHO WITH PSILI-foldMapping '\x1fe4' s = Yield '\x03c1' (s :*: '\x0313' :*: '\x0000')+foldMapping '\x1fe4' s = Yield '\x03c1' (CC s '\x0313' '\x0000') -- GREEK SMALL LETTER UPSILON WITH PERISPOMENI-foldMapping '\x1fe6' s = Yield '\x03c5' (s :*: '\x0342' :*: '\x0000')+foldMapping '\x1fe6' s = Yield '\x03c5' (CC s '\x0342' '\x0000') -- GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI-foldMapping '\x1fe7' s = Yield '\x03c5' (s :*: '\x0308' :*: '\x0342')+foldMapping '\x1fe7' s = Yield '\x03c5' (CC s '\x0308' '\x0342') -- GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI-foldMapping '\x1ff2' s = Yield '\x1f7c' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1ff2' s = Yield '\x1f7c' (CC s '\x03b9' '\x0000') -- GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI-foldMapping '\x1ff3' s = Yield '\x03c9' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1ff3' s = Yield '\x03c9' (CC s '\x03b9' '\x0000') -- GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI-foldMapping '\x1ff4' s = Yield '\x03ce' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1ff4' s = Yield '\x03ce' (CC s '\x03b9' '\x0000') -- GREEK SMALL LETTER OMEGA WITH PERISPOMENI-foldMapping '\x1ff6' s = Yield '\x03c9' (s :*: '\x0342' :*: '\x0000')+foldMapping '\x1ff6' s = Yield '\x03c9' (CC s '\x0342' '\x0000') -- GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI-foldMapping '\x1ff7' s = Yield '\x03c9' (s :*: '\x0342' :*: '\x03b9')+foldMapping '\x1ff7' s = Yield '\x03c9' (CC s '\x0342' '\x03b9') -- GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI-foldMapping '\x1ffc' s = Yield '\x03c9' (s :*: '\x03b9' :*: '\x0000')+foldMapping '\x1ffc' s = Yield '\x03c9' (CC s '\x03b9' '\x0000') -- LATIN SMALL LIGATURE FF-foldMapping '\xfb00' s = Yield '\x0066' (s :*: '\x0066' :*: '\x0000')+foldMapping '\xfb00' s = Yield '\x0066' (CC s '\x0066' '\x0000') -- LATIN SMALL LIGATURE FI-foldMapping '\xfb01' s = Yield '\x0066' (s :*: '\x0069' :*: '\x0000')+foldMapping '\xfb01' s = Yield '\x0066' (CC s '\x0069' '\x0000') -- LATIN SMALL LIGATURE FL-foldMapping '\xfb02' s = Yield '\x0066' (s :*: '\x006c' :*: '\x0000')+foldMapping '\xfb02' s = Yield '\x0066' (CC s '\x006c' '\x0000') -- LATIN SMALL LIGATURE FFI-foldMapping '\xfb03' s = Yield '\x0066' (s :*: '\x0066' :*: '\x0069')+foldMapping '\xfb03' s = Yield '\x0066' (CC s '\x0066' '\x0069') -- LATIN SMALL LIGATURE FFL-foldMapping '\xfb04' s = Yield '\x0066' (s :*: '\x0066' :*: '\x006c')+foldMapping '\xfb04' s = Yield '\x0066' (CC s '\x0066' '\x006c') -- LATIN SMALL LIGATURE LONG S T-foldMapping '\xfb05' s = Yield '\x0073' (s :*: '\x0074' :*: '\x0000')+foldMapping '\xfb05' s = Yield '\x0073' (CC s '\x0074' '\x0000') -- LATIN SMALL LIGATURE ST-foldMapping '\xfb06' s = Yield '\x0073' (s :*: '\x0074' :*: '\x0000')+foldMapping '\xfb06' s = Yield '\x0073' (CC s '\x0074' '\x0000') -- ARMENIAN SMALL LIGATURE MEN NOW-foldMapping '\xfb13' s = Yield '\x0574' (s :*: '\x0576' :*: '\x0000')+foldMapping '\xfb13' s = Yield '\x0574' (CC s '\x0576' '\x0000') -- ARMENIAN SMALL LIGATURE MEN ECH-foldMapping '\xfb14' s = Yield '\x0574' (s :*: '\x0565' :*: '\x0000')+foldMapping '\xfb14' s = Yield '\x0574' (CC s '\x0565' '\x0000') -- ARMENIAN SMALL LIGATURE MEN INI-foldMapping '\xfb15' s = Yield '\x0574' (s :*: '\x056b' :*: '\x0000')+foldMapping '\xfb15' s = Yield '\x0574' (CC s '\x056b' '\x0000') -- ARMENIAN SMALL LIGATURE VEW NOW-foldMapping '\xfb16' s = Yield '\x057e' (s :*: '\x0576' :*: '\x0000')+foldMapping '\xfb16' s = Yield '\x057e' (CC s '\x0576' '\x0000') -- ARMENIAN SMALL LIGATURE MEN XEH-foldMapping '\xfb17' s = Yield '\x0574' (s :*: '\x056d' :*: '\x0000')-foldMapping c s = Yield (toLower c) (s :*: '\0' :*: '\0')+foldMapping '\xfb17' s = Yield '\x0574' (CC s '\x056d' '\x0000')+foldMapping c s = Yield (toLower c) (CC s '\0' '\0')
Data/Text/Fusion/Common.hs view
@@ -98,7 +98,7 @@ , zipWith ) where -import Prelude (Bool(..), Char, Either(..), Eq(..), Int, Integral, Maybe(..),+import Prelude (Bool(..), Char, Eq(..), Int, Integral, Maybe(..), Ord(..), String, (.), ($), (+), (-), (*), (++), (&&), fromIntegral, otherwise) import qualified Data.List as L@@ -121,35 +121,36 @@ next (x:xs) = Yield x xs unstreamList :: Stream a -> [a]-{-# INLINE [0] unstreamList #-} 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 #-} -- ---------------------------------------------------------------------------- -- * 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 (S2 :*: s0) (len+1)+cons w (Stream next0 s0 len) = Stream next (C1 s0) (len+1) where- {-# INLINE next #-}- next (S2 :*: s) = Yield w (S1 :*: s)- next (S1 :*: s) = case next0 s of+ next (C1 s) = Yield w (C0 s)+ next (C0 s) = case next0 s of Done -> Done- Skip s' -> Skip (S1 :*: s')- Yield x s' -> Yield x (S1 :*: s')+ 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- {-# INLINE next #-} next (J xs) = case next0 xs of Done -> Yield w N Skip xs' -> Skip (J xs')@@ -157,20 +158,22 @@ next N = Done {-# INLINE [0] snoc #-} +data E l r = L {-# UNPACK #-} !l+ | R {-# UNPACK #-} !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 (Left s01) (len1 + len2)+ Stream next (L s01) (len1 + len2) where- {-# INLINE next #-}- next (Left s1) = case next0 s1 of- Done -> Skip (Right s02)- Skip s1' -> Skip (Left s1')- Yield x s1' -> Yield x (Left s1')- next (Right s2) = case next1 s2 of+ 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 (Right s2')- Yield x s2' -> Yield x (Right s2')+ 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.@@ -180,8 +183,8 @@ where loop_head !s = case next s of Yield x _ -> x- Skip s' -> loop_head s'- Done -> streamError "head" "Empty stream"+ Skip s' -> loop_head s'+ Done -> streamError "head" "Empty stream" {-# INLINE [0] head #-} -- | /O(1)/ Returns the first character and remainder of a 'Stream@@ -213,34 +216,34 @@ -- | /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 (False :*: s0) (len-1)+tail (Stream next0 s0 len) = Stream next (C0 s0) (len-1) where- {-# INLINE next #-}- next (False :*: s) = case next0 s of- Done -> emptyError "tail"- Skip s' -> Skip (False :*: s')- Yield _ s' -> Skip (True :*: s')- next (True :*: s) = case next0 s of- Done -> Done- Skip s' -> Skip (True :*: s')- Yield x s' -> Yield x (True :*: s')+ 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 (N :*: s0) (len-1)+init (Stream next0 s0 len) = Stream next (Init0 s0) (len-1) where- {-# INLINE next #-}- next (N :*: s) = case next0 s of+ next (Init0 s) = case next0 s of Done -> emptyError "init"- Skip s' -> Skip (N :*: s')- Yield x s' -> Skip (J x :*: s')- next (J x :*: s) = case next0 s of+ 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 (J x :*: s')- Yield x' s' -> Yield x (J x' :*: s')+ 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.@@ -283,7 +286,6 @@ map :: (Char -> Char) -> Stream Char -> Stream Char map f (Stream next0 s0 len) = Stream next s0 len where- {-# INLINE next #-} next !s = case next0 s of Done -> Done Skip s' -> Skip s'@@ -295,22 +297,24 @@ 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 (s0 :*: N :*: S1) len+intersperse c (Stream next0 s0 len) = Stream next (I1 s0) len where- {-# INLINE next #-}- next (s :*: N :*: S1) = case next0 s of+ next (I1 s) = case next0 s of Done -> Done- Skip s' -> Skip (s' :*: N :*: S1)- Yield x s' -> Skip (s' :*: J x :*: S1)- next (s :*: J x :*: S1) = Yield x (s :*: N :*: S2)- next (s :*: N :*: S2) = case next0 s of+ 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 (s' :*: N :*: S2)- Yield x s' -> Yield c (s' :*: J x :*: S1)- next _ = internalError "intersperse"+ Skip s' -> Skip (I3 s')+ Yield x s' -> Yield c (I2 s' x) {-# INLINE [0] intersperse #-} -- ----------------------------------------------------------------------------@@ -325,17 +329,16 @@ -- functions may map one input character to two or three output -- characters. -caseConvert :: (forall s. Char -> s -> Step (PairS (PairS s Char) Char) Char)+caseConvert :: (forall s. Char -> s -> Step (CC s) Char) -> Stream Char -> Stream Char-caseConvert remap (Stream next0 s0 len) = Stream next (s0 :*: '\0' :*: '\0') len+caseConvert remap (Stream next0 s0 len) = Stream next (CC s0 '\0' '\0') len where- {-# INLINE next #-}- next (s :*: '\0' :*: _) =+ next (CC s '\0' _) = case next0 s of Done -> Done- Skip s' -> Skip (s' :*: '\0' :*: '\0')+ Skip s' -> Skip (CC s' '\0' '\0') Yield c s' -> remap c s'- next (s :*: a :*: b) = Yield a (s :*: b :*: '\0')+ 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@@ -480,11 +483,13 @@ -- | /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@.@@ -590,21 +595,22 @@ | n < 0 = empty | otherwise = Stream next 0 (fromIntegral n) -- HINT maybe too low where- {-# INLINE next #-} 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 (0 :*: s0) (fromIntegral (max 0 n) * len)+ Stream next (RI s0 0) (fromIntegral (max 0 n) * len) where- next (k :*: s)+ next (RI s k) | k >= n = Done | otherwise = case next0 s of- Done -> Skip (k+1 :*: s0)- Skip s' -> Skip (k :*: s')- Yield x s' -> Yield x (k :*: s')+ 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@@ -772,7 +778,6 @@ filter :: (Char -> Bool) -> Stream Char -> Stream Char filter 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'@@ -781,7 +786,7 @@ {-# INLINE [0] filter #-} {-# RULES- "Stream filter/filter fusion" forall p q s.+ "STREAM filter/filter fusion" forall p q s. filter p (filter q s) = filter (\x -> q x && p x) s #-} @@ -816,7 +821,6 @@ zipWith f (Stream next0 sa0 len1) (Stream next1 sb0 len2) = Stream next (sa0 :*: sb0 :*: N) (smaller len1 len2) where- {-# INLINE next #-} next (sa :*: sb :*: N) = case next0 sa of Done -> Done Skip sa' -> Skip (sa' :*: sb :*: N)
Data/Text/Fusion/Internal.hs view
@@ -15,7 +15,8 @@ module Data.Text.Fusion.Internal (- M(..)+ CC(..)+ , M(..) , M8 , PairS(..) , S(..)@@ -27,6 +28,9 @@ 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
Data/Text/Lazy.hs view
@@ -119,6 +119,7 @@ , splitAt , spanBy , break+ , breakEnd , breakBy , group , groupBy@@ -163,11 +164,12 @@ -- , sort ) where -import Prelude (Char, Bool(..), Int, Maybe(..), String,+import Prelude (Char, Bool(..), Maybe(..), String, Eq(..), Ord(..), Read(..), Show(..), (&&), (+), (-), (.), ($), (++), div, flip, fromIntegral, not, otherwise) import qualified Prelude as P+import Control.DeepSeq (NFData(..)) import Data.Int (Int64) import qualified Data.List as L import Data.Char (isSpace)@@ -206,6 +208,10 @@ instance IsString Text where fromString = pack +instance NFData Text where+ rnf Empty = ()+ rnf (Chunk _ ts) = rnf ts+ -- | /O(n)/ Convert a 'String' into a 'Text'. -- -- This function is subject to array fusion.@@ -376,7 +382,7 @@ -- 'Text's and concatenates the list after interspersing the first -- argument between each element of the list. intercalate :: Text -> [Text] -> Text-intercalate t ts = unstream (S.intercalate (stream t) (L.map stream ts))+intercalate t = concat . (L.intersperse t) {-# INLINE intercalate #-} -- | /O(n)/ The 'intersperse' function takes a character and places it@@ -445,7 +451,7 @@ where rev a Empty = a rev a (Chunk t ts) = rev (Chunk (T.reverse t) a) ts --- | /O(m)*O(n)/ Replace every occurrence of one substring with another.+-- | /O(m+n)/ Replace every occurrence of one substring with another. replace :: Text -- ^ Text to search for -> Text -- ^ Replacement text -> Text -- ^ Input text@@ -542,18 +548,20 @@ foldr1 f t = S.foldr1 f (stream t) {-# INLINE foldr1 #-} --- | /O(n)/ Concatenate a list of 'Text's. Subject to array fusion.+-- | /O(n)/ Concatenate a list of 'Text's. concat :: [Text] -> Text-concat ts = unstream (S.concat (L.map stream ts))+concat = to+ where+ go Empty css = to css+ go (Chunk c cs) css = Chunk c (go cs css)+ to [] = Empty+ to (cs:css) = go cs css {-# INLINE concat #-} -- | /O(n)/ Map a function over a 'Text' that results in a 'Text', and--- concatenate the results. This function is subject to array fusion.------ Note: if in 'concatMap' @f@ @t@, @f@ is defined in terms of fusible--- functions, it will also be fusible.+-- concatenate the results. concatMap :: (Char -> Text) -> Text -> Text-concatMap f t = unstream (S.concatMap (stream . f) (stream t))+concatMap f = concat . foldr ((:) . f) [] {-# INLINE concatMap #-} -- | /O(n)/ 'any' @p@ @t@ determines whether any character in the@@ -637,11 +645,11 @@ (s', ys) = mapAccumR f s xs -- | /O(n*m)/ 'replicate' @n@ @t@ is a 'Text' consisting of the input--- @t@ repeated @n@ times. Subject to fusion.+-- @t@ repeated @n@ times. replicate :: Int64 -> Text -> Text-replicate n t- | isSingleton t = replicateChar n (head t)- | otherwise = unstream (S.replicateI n (S.stream t))+replicate n t = concat (rep 0)+ where rep i | i >= n = []+ | otherwise = t : rep (i+1) {-# INLINE replicate #-} -- | /O(n)/ 'replicateChar' @n@ @c@ is a 'Text' of length @n@ with @c@ the@@ -873,6 +881,18 @@ [] -> (src, empty) (x:_) -> let h :*: t = splitAtWord x src in (h, t)++-- | /O(n+m)/ Similar to 'break', but searches from the end of the string.+--+-- The first element of the returned tuple is the prefix of @haystack@+-- up to and including the last match of @needle@. The second is the+-- remainder of @haystack@, following the match.+--+-- > breakEnd "::" "a::b::c" ==> ("a::b::", "c")+breakEnd :: Text -> Text -> (Text, Text)+breakEnd pat src = let (a,b) = break (reverse pat) (reverse src)+ in (reverse b, reverse a)+{-# INLINE breakEnd #-} -- | /O(n+m)/ Find all non-overlapping instances of @needle@ in -- @haystack@. The first element of the returned pair is the prefix
Data/Text/Lazy/Encoding/Fusion.hs view
@@ -53,7 +53,6 @@ streamUtf8 onErr bs0 = Stream next (bs0 :*: empty :*: 0) unknownSize where empty = S N N N N- {-# INLINE next #-} next (bs@(Chunk ps _) :*: S N _ _ _ :*: i) | i < len && U8.validate1 a = Yield (unsafeChr8 a) (bs :*: empty :*: i+1)@@ -80,7 +79,6 @@ Yield (U8.chr4 a b c d) es _ -> consume st where es = bs :*: empty :*: i- {-# INLINE consume #-} consume (bs@(Chunk ps rest) :*: s :*: i) | i >= B.length ps = consume (rest :*: s :*: 0) | otherwise =
Data/Text/Lazy/Internal.hs view
@@ -31,7 +31,7 @@ ) where import qualified Data.Text.Internal as T-import qualified Data.Text as T+import Data.Text () import Data.Typeable (Typeable) import Data.Word (Word16) import Foreign.Storable (sizeOf)
Data/Text/Lazy/Search.hs view
@@ -23,7 +23,6 @@ import Data.Int (Int64) import Data.Word (Word16, Word64) import qualified Data.Text.Internal as T-import qualified Data.Text as T import Data.Text.Fusion.Internal (PairS(..)) import Data.Text.Lazy.Internal (Text(..), foldlChunks) import Data.Bits ((.|.), (.&.))
scripts/CaseFolding.hs view
@@ -32,11 +32,11 @@ mapCF :: [Fold] -> [String] mapCF ms = typ ++ (map nice . filter p $ ms) ++ [last] where- typ = ["foldMapping :: forall s. Char -> s -> Step (PairS (PairS s Char) Char) Char"+ typ = ["foldMapping :: forall s. Char -> s -> Step (CC s) Char" ,"{-# INLINE foldMapping #-}"]- last = "foldMapping c s = Yield (toLower c) (s :!: '\\0' :!: '\\0')"+ last = "foldMapping c s = Yield (toLower c) (CC s '\\0' '\\0')" nice c = "-- " ++ name c ++ "\n" ++- "foldMapping " ++ showC (code c) ++ " s = Yield " ++ x ++ " (s :!: " ++ y ++ " :!: " ++ z ++ ")"+ "foldMapping " ++ showC (code c) ++ " s = Yield " ++ x ++ " (CC s " ++ y ++ " " ++ z ++ ")" where [x,y,z] = (map showC . take 3) (mapping c ++ repeat '\0') p f = status f `elem` "CF" && mapping f /= [toLower (code f)]
scripts/SpecialCasing.hs view
@@ -36,11 +36,11 @@ mapSC :: String -> (Case -> String) -> (Char -> Char) -> [Case] -> [String] mapSC which access twiddle ms = typ ++ (map nice . filter p $ ms) ++ [last] where- typ = [which ++ "Mapping :: forall s. Char -> s -> Step (PairS (PairS s Char) Char) Char"+ typ = [which ++ "Mapping :: forall s. Char -> s -> Step (CC s) Char" ,"{-# INLINE " ++ which ++ "Mapping #-}"]- last = which ++ "Mapping c s = Yield (to" ++ ucFirst which ++ " c) (s :!: '\\0' :!: '\\0')"+ last = which ++ "Mapping c s = Yield (to" ++ ucFirst which ++ " c) (CC s '\\0' '\\0')" nice c = "-- " ++ name c ++ "\n" ++- which ++ "Mapping " ++ showC (code c) ++ " s = Yield " ++ x ++ " (s :!: " ++ y ++ " :!: " ++ z ++ ")"+ which ++ "Mapping " ++ showC (code c) ++ " s = Yield " ++ x ++ " (CC s " ++ y ++ " " ++ z ++ ")" where [x,y,z] = (map showC . take 3) (access c ++ repeat '\0') p c = [k] /= a && a /= [twiddle k] && null (conditions c) where a = access c
+ tests/Benchmarks.hs view
@@ -0,0 +1,400 @@+{-# LANGUAGE GADTs, MagicHash #-}++import qualified Data.ByteString.Char8 as BS+import qualified Data.ByteString.Lazy.Char8 as BL+import qualified Data.ByteString.Lazy.Internal as BL+import Control.Monad.Trans (liftIO)+import Control.Exception (evaluate)+import Criterion.Main+import Data.Char+import qualified Codec.Binary.UTF8.Generic as UTF8+import qualified Data.Text as TS+import qualified Data.Text.Lazy as TL+import qualified Data.List as L+import qualified Data.Text.Encoding as TS+import qualified Data.Text.Lazy.Encoding as TL+import qualified Criterion.MultiMap as M+import Criterion.Config+import GHC.Base+++myConfig+ | False = defaultConfig {+ -- Always display an 800x600 window.+ cfgPlot = M.singleton KernelDensity (Window 800 600)+ }+ | otherwise = defaultConfig++instance NFData BS.ByteString++instance NFData BL.ByteString where+ rnf BL.Empty = ()+ rnf (BL.Chunk _ ts) = rnf ts++data B where+ B :: NFData a => a -> B++instance NFData B where+ rnf (B b) = rnf b++main = do+ bsa <- BS.readFile "text/test/russian.txt"+ let tsa = TS.decodeUtf8 bsa+ tsb = TS.toUpper tsa+ tla = TL.fromChunks (TS.chunksOf 16376 tsa)+ tlb = TL.fromChunks (TS.chunksOf 16376 tsb)+ bsb = TS.encodeUtf8 tsb+ bla = BL.fromChunks (chunksOf 16376 bsa)+ blb = BL.fromChunks (chunksOf 16376 bsb)+ bsa_len = BS.length bsa+ tsa_len = TS.length tsa+ bla_len = BL.length bla+ tla_len = TL.length tla+ la = UTF8.toString bsa+ la_len = L.length la+ tsb_len = TS.length tsb+ lb = TS.unpack tsb+ bsl = BS.lines bsa+ bll = BL.lines bla+ tsl = TS.lines tsa+ tll = TL.lines tla+ ll = L.lines la+ defaultMainWith+ myConfig+ (liftIO . evaluate $+ rnf [B tsa, B tsb, B tla, B tlb, B bsa, B bsb, B bla, B blb,+ B bsa_len, B tsa_len, B bla_len, B tla_len, B la, B la_len,+ B tsb_len, B lb, B bsl, B bll, B tsl, B tll, B ll])+ [+ bgroup "append" [+ bench "ts" $ nf (TS.append tsb) tsa+ , bench "tl" $ nf (TL.append tlb) tla+ , bench "bs" $ nf (BS.append bsb) bsa+ , bench "bl" $ nf (BL.append blb) bla+ , bench "l" $ nf ((++) lb) la+ ],+ bgroup "concat" [+ bench "ts" $ nf TS.concat tsl+ , bench "tl" $ nf TL.concat tll+ , bench "bs" $ nf BS.concat bsl+ , bench "bl" $ nf BL.concat bll+ , bench "l" $ nf L.concat ll+ ],+ bgroup "cons" [+ bench "ts" $ nf (TS.cons c) tsa+ , bench "tl" $ nf (TL.cons c) tla+ , bench "bs" $ nf (BS.cons c) bsa+ , bench "bl" $ nf (BL.cons c) bla+ , bench "l" $ nf (c:) la+ ],+ bgroup "concatMap" [+ bench "ts" $ nf (TS.concatMap (TS.replicate 3 . TS.singleton)) tsa+ , bench "tl" $ nf (TL.concatMap (TL.replicate 3 . TL.singleton)) tla+ , bench "bs" $ nf (BS.concatMap (BS.replicate 3)) bsa+ , bench "bl" $ nf (BL.concatMap (BL.replicate 3)) bla+ , bench "l" $ nf (L.concatMap (L.replicate 3 . (:[]))) la+ ],+ bgroup "decode" [+ bench "ts" $ nf TS.decodeUtf8 bsa+ , bench "tl" $ nf TL.decodeUtf8 bla+ , bench "bs" $ nf BS.unpack bsa+ , bench "bl" $ nf BL.unpack bla+ , bench "l" $ nf UTF8.toString bsa+ ],+ bgroup "drop" [+ bench "ts" $ nf (TS.drop (tsa_len `div` 3)) tsa+ , bench "tl" $ nf (TL.drop (tla_len `div` 3)) tla+ , bench "bs" $ nf (BS.drop (bsa_len `div` 3)) bsa+ , bench "bl" $ nf (BL.drop (bla_len `div` 3)) bla+ , bench "l" $ nf (L.drop (la_len `div` 3)) la+ ],+ bgroup "filter" [+ bench "ts" $ nf (TS.filter p0) tsa+ , bench "tl" $ nf (TL.filter p0) tla+ , bench "bs" $ nf (BS.filter p0) bsa+ , bench "bl" $ nf (BL.filter p0) bla+ , bench "l" $ nf (L.filter p0) la+ ],+ bgroup "filter.filter" [+ bench "ts" $ nf (TS.filter p1 . TS.filter p0) tsa+ , bench "tl" $ nf (TL.filter p1 . TL.filter p0) tla+ , bench "bs" $ nf (BS.filter p1 . BS.filter p0) bsa+ , bench "bl" $ nf (BL.filter p1 . BL.filter p0) bla+ , bench "l" $ nf (L.filter p1 . L.filter p0) la+ ],+ bgroup "foldl'" [+ bench "ts" $ nf (TS.foldl' len 0) tsa+ , bench "tl" $ nf (TL.foldl' len 0) tla+ , bench "bs" $ nf (BS.foldl' len 0) bsa+ , bench "bl" $ nf (BL.foldl' len 0) bla+ , bench "l" $ nf (L.foldl' len 0) la+ ],+ bgroup "foldr" [+ bench "ts" $ nf (L.length . TS.foldr (:) []) tsa+ , bench "tl" $ nf (L.length . TL.foldr (:) []) tla+ , bench "bs" $ nf (L.length . BS.foldr (:) []) bsa+ , bench "bl" $ nf (L.length . BL.foldr (:) []) bla+ , bench "l" $ nf (L.length . L.foldr (:) []) la+ ],+ bgroup "head" [+ bench "ts" $ nf TS.head tsa+ , bench "tl" $ nf TL.head tla+ , bench "bs" $ nf BS.head bsa+ , bench "bl" $ nf BL.head bla+ , bench "l" $ nf L.head la+ ],+ bgroup "init" [+ bench "ts" $ nf TS.init tsa+ , bench "tl" $ nf TL.init tla+ , bench "bs" $ nf BS.init bsa+ , bench "bl" $ nf BL.init bla+ , bench "l" $ nf L.init la+ ],+ bgroup "intercalate" [+ bench "ts" $ nf (TS.intercalate tsw) tsl+ , bench "tl" $ nf (TL.intercalate tlw) tll+ , bench "bs" $ nf (BS.intercalate bsw) bsl+ , bench "bl" $ nf (BL.intercalate blw) bll+ , bench "l" $ nf (L.intercalate lw) ll+ ],+ bgroup "intersperse" [+ bench "ts" $ nf (TS.intersperse c) tsa+ , bench "tl" $ nf (TL.intersperse c) tla+ , bench "bs" $ nf (BS.intersperse c) bsa+ , bench "bl" $ nf (BL.intersperse c) bla+ , bench "l" $ nf (L.intersperse c) la+ ],+ bgroup "isInfixOf" [+ bench "ts" $ nf (TS.isInfixOf tsw) tsa+ , bench "tl" $ nf (TL.isInfixOf tlw) tla+ , bench "bs" $ nf (BS.isInfixOf bsw) bsa+ -- no isInfixOf for lazy bytestrings+ , bench "l" $ nf (L.isInfixOf lw) la+ ],+ bgroup "last" [+ bench "ts" $ nf TS.last tsa+ , bench "tl" $ nf TL.last tla+ , bench "bs" $ nf BS.last bsa+ , bench "bl" $ nf BL.last bla+ , bench "l" $ nf L.last la+ ],+ bgroup "map" [+ bench "ts" $ nf (TS.map f) tsa+ , bench "tl" $ nf (TL.map f) tla+ , bench "bs" $ nf (BS.map f) bsa+ , bench "bl" $ nf (BL.map f) bla+ , bench "l" $ nf (L.map f) la+ ],+ bgroup "map.map" [+ bench "ts" $ nf (TS.map f . TS.map f) tsa+ , bench "tl" $ nf (TL.map f . TL.map f) tla+ , bench "bs" $ nf (BS.map f . BS.map f) bsa+ , bench "bl" $ nf (BL.map f . BL.map f) bla+ , bench "l" $ nf (L.map f . L.map f) la+ ],+ bgroup "replicate char" [+ bench "ts" $ nf (TS.replicate bsa_len) (TS.singleton c)+ , bench "tl" $ nf (TL.replicate (fromIntegral bsa_len)) (TL.singleton c)+ , bench "bs" $ nf (BS.replicate bsa_len) c+ , bench "bl" $ nf (BL.replicate (fromIntegral bsa_len)) c+ , bench "l" $ nf (L.replicate bsa_len) c+ ],+ bgroup "replicate string" [+ bench "ts" $ nf (TS.replicate (bsa_len `div` TS.length tsw)) tsw+ , bench "tl" $ nf (TL.replicate (fromIntegral bsa_len `div` TL.length tlw)) tlw+ , bench "l" $ nf (replicat (bsa_len `div` TS.length tsw)) lw+ ],+ bgroup "reverse" [+ bench "ts" $ nf TS.reverse tsa+ , bench "tl" $ nf TL.reverse tla+ , bench "bs" $ nf BS.reverse bsa+ , bench "bl" $ nf BL.reverse bla+ , bench "l" $ nf L.reverse la+ ],+ bgroup "take" [+ bench "ts" $ nf (TS.take (tsa_len `div` 3)) tsa+ , bench "tl" $ nf (TL.take (tla_len `div` 3)) tla+ , bench "bs" $ nf (BS.take (bsa_len `div` 3)) bsa+ , bench "bl" $ nf (BL.take (bla_len `div` 3)) bla+ , bench "l" $ nf (L.take (la_len `div` 3)) la+ ],+ bgroup "tail" [+ bench "ts" $ nf TS.tail tsa+ , bench "tl" $ nf TL.tail tla+ , bench "bs" $ nf BS.tail bsa+ , bench "bl" $ nf BL.tail bla+ , bench "l" $ nf L.tail la+ ],+ bgroup "toLower" [+ bench "ts" $ nf TS.toLower tsa+ , bench "tl" $ nf TL.toLower tla+ , bench "bs" $ nf (BS.map toLower) bsa+ , bench "bl" $ nf (BL.map toLower) bla+ , bench "l" $ nf (L.map toLower) la+ ],+ bgroup "toUpper" [+ bench "ts" $ nf TS.toUpper tsa+ , bench "tl" $ nf TL.toUpper tla+ , bench "bs" $ nf (BS.map toUpper) bsa+ , bench "bl" $ nf (BL.map toUpper) bla+ , bench "l" $ nf (L.map toUpper) la+ ],+ bgroup "words" [+ bench "ts" $ nf TS.words tsa+ , bench "tl" $ nf TL.words tla+ , bench "bs" $ nf BS.words bsa+ , bench "bl" $ nf BL.words bla+ , bench "l" $ nf L.words la+ ],+ bgroup "zipWith" [+ bench "ts" $ nf (TS.zipWith min tsb) tsa+ , bench "tl" $ nf (TL.zipWith min tlb) tla+ , bench "bs" $ nf (BS.zipWith min bsb) bsa+ , bench "bl" $ nf (BL.zipWith min blb) bla+ , bench "l" $ nf (L.zipWith min lb) la+ ],+ bgroup "length" [+ bgroup "cons" [+ bench "ts" $ nf (TS.length . TS.cons c) tsa+ , bench "tl" $ nf (TL.length . TL.cons c) tla+ , bench "bs" $ nf (BS.length . BS.cons c) bsa+ , bench "bl" $ nf (BL.length . BL.cons c) bla+ , bench "l" $ nf (L.length . (:) c) la+ ],+ bgroup "decode" [+ bench "ts" $ nf (TS.length . TS.decodeUtf8) bsa+ , bench "tl" $ nf (TL.length . TL.decodeUtf8) bla+ , bench "bs" $ nf (L.length . BS.unpack) bsa+ , bench "bl" $ nf (L.length . BL.unpack) bla+ , bench "utf8-string" $ nf (L.length . UTF8.toString) bsa+ ],+ bgroup "drop" [+ bench "ts" $ nf (TS.length . TS.drop (tsa_len `div` 3)) tsa+ , bench "tl" $ nf (TL.length . TL.drop (tla_len `div` 3)) tla+ , bench "bs" $ nf (BS.length . BS.drop (bsa_len `div` 3)) bsa+ , bench "bl" $ nf (BL.length . BL.drop (bla_len `div` 3)) bla+ , bench "l" $ nf (L.length . L.drop (la_len `div` 3)) la+ ],+ bgroup "filter" [+ bench "ts" $ nf (TS.length . TS.filter p0) tsa+ , bench "tl" $ nf (TL.length . TL.filter p0) tla+ , bench "bs" $ nf (BS.length . BS.filter p0) bsa+ , bench "bl" $ nf (BL.length . BL.filter p0) bla+ , bench "l" $ nf (L.length . L.filter p0) la+ ],+ bgroup "filter.filter" [+ bench "ts" $ nf (TS.length . TS.filter p1 . TS.filter p0) tsa+ , bench "tl" $ nf (TL.length . TL.filter p1 . TL.filter p0) tla+ , bench "bs" $ nf (BS.length . BS.filter p1 . BS.filter p0) bsa+ , bench "bl" $ nf (BL.length . BL.filter p1 . BL.filter p0) bla+ , bench "l" $ nf (L.length . L.filter p1 . L.filter p0) la+ ],+ bgroup "init" [+ bench "ts" $ nf (TS.length . TS.init) tsa+ , bench "tl" $ nf (TL.length . TL.init) tla+ , bench "bs" $ nf (BS.length . BS.init) bsa+ , bench "bl" $ nf (BL.length . BL.init) bla+ , bench "l" $ nf (L.length . L.init) la+ ],+ bgroup "intercalate" [+ bench "ts" $ nf (TS.length . TS.intercalate tsw) tsl+ , bench "tl" $ nf (TL.length . TL.intercalate tlw) tll+ , bench "bs" $ nf (BS.length . BS.intercalate bsw) bsl+ , bench "bl" $ nf (BL.length . BL.intercalate blw) bll+ , bench "l" $ nf (L.length . L.intercalate lw) ll+ ],+ bgroup "intersperse" [+ bench "ts" $ nf (TS.length . TS.intersperse c) tsa+ , bench "tl" $ nf (TL.length . TL.intersperse c) tla+ , bench "bs" $ nf (BS.length . BS.intersperse c) bsa+ , bench "bl" $ nf (BL.length . BL.intersperse c) bla+ , bench "l" $ nf (L.length . L.intersperse c) la+ ],+ bgroup "map" [+ bench "ts" $ nf (TS.length . TS.map f) tsa+ , bench "tl" $ nf (TL.length . TL.map f) tla+ , bench "bs" $ nf (BS.length . BS.map f) bsa+ , bench "bl" $ nf (BL.length . BL.map f) bla+ , bench "l" $ nf (L.length . L.map f) la+ ],+ bgroup "map.map" [+ bench "ts" $ nf (TS.length . TS.map f . TS.map f) tsa+ , bench "tl" $ nf (TL.length . TL.map f . TL.map f) tla+ , bench "bs" $ nf (BS.length . BS.map f . BS.map f) bsa+ , bench "l" $ nf (L.length . L.map f . L.map f) la+ ],+ bgroup "replicate char" [+ bench "ts" $ nf (TS.length . TS.replicate bsa_len) (TS.singleton c)+ , bench "tl" $ nf (TL.length . TL.replicate (fromIntegral bsa_len)) (TL.singleton c)+ , bench "bs" $ nf (BS.length . BS.replicate bsa_len) c+ , bench "bl" $ nf (BL.length . BL.replicate (fromIntegral bsa_len)) c+ , bench "l" $ nf (L.length . L.replicate bsa_len) c+ ],+ bgroup "replicate string" [+ bench "ts" $ nf (TS.length . TS.replicate (bsa_len `div` TS.length tsw)) tsw+ , bench "tl" $ nf (TL.length . TL.replicate (fromIntegral bsa_len `div` TL.length tlw)) tlw+ , bench "l" $ nf (L.length . replicat (bsa_len `div` TS.length tsw)) lw+ ],+ bgroup "take" [+ bench "ts" $ nf (TS.length . TS.take (tsa_len `div` 3)) tsa+ , bench "tl" $ nf (TL.length . TL.take (tla_len `div` 3)) tla+ , bench "bs" $ nf (BS.length . BS.take (bsa_len `div` 3)) bsa+ , bench "bl" $ nf (BL.length . BL.take (bla_len `div` 3)) bla+ , bench "l" $ nf (L.length . L.take (la_len `div` 3)) la+ ],+ bgroup "tail" [+ bench "ts" $ nf (TS.length . TS.tail) tsa+ , bench "tl" $ nf (TL.length . TL.tail) tla+ , bench "bs" $ nf (BS.length . BS.tail) bsa+ , bench "bl" $ nf (BL.length . BL.tail) bla+ , bench "l" $ nf (L.length . L.tail) la+ ],+ bgroup "toLower" [+ bench "ts" $ nf (TS.length . TS.toLower) tsa+ , bench "tl" $ nf (TL.length . TL.toLower) tla+ , bench "bs" $ nf (BS.length . BS.map toLower) bsa+ , bench "bl" $ nf (BL.length . BL.map toLower) bla+ , bench "l" $ nf (L.length . L.map toLower) la+ ],+ bgroup "toUpper" [+ bench "ts" $ nf (TS.length . TS.toUpper) tsa+ , bench "tl" $ nf (TL.length . TL.toUpper) tla+ , bench "bs" $ nf (BS.length . BS.map toUpper) bsa+ , bench "bl" $ nf (BL.length . BL.map toUpper) bla+ , bench "l" $ nf (L.length . L.map toUpper) la+ ],+ bgroup "words" [+ bench "ts" $ nf (L.length . TS.words) tsa+ , bench "tl" $ nf (L.length . TL.words) tla+ , bench "bs" $ nf (L.length . BS.words) bsa+ , bench "bl" $ nf (L.length . BL.words) bla+ , bench "l" $ nf (L.length . L.words) la+ ],+ bgroup "zipWith" [+ bench "ts" $ nf (TS.length . TS.zipWith min tsb) tsa+ , bench "tl" $ nf (TL.length . TL.zipWith min tlb) tla+ , bench "bs" $ nf (L.length . BS.zipWith min bsb) bsa+ , bench "bl" $ nf (L.length . BL.zipWith min blb) bla+ , bench "l" $ nf (L.length . L.zipWith min lb) la+ ]+ ]+ ]+ where+ c = 'й'+ p0 = (== c)+ p1 = (/= 'д')+ lw = "право"+ bsw = UTF8.fromString lw+ blw = BL.fromChunks [bsw]+ tsw = TS.pack lw+ tlw = TL.fromChunks [tsw]+ f (C# c#) = C# (chr# (ord# c# +# 1#))+ len l _ = l + (1::Int)+ replicat n = concat . L.replicate n++chunksOf :: Int -> BS.ByteString -> [BS.ByteString]+chunksOf k = go+ where+ go t = case BS.splitAt k t of+ (a,b) | BS.null a -> []+ | otherwise -> a : go b
tests/Makefile view
@@ -2,9 +2,10 @@ ghc := ghc ghc-opt-flags = -O0 ghc-base-flags := -funbox-strict-fields -package criterion \- -package bytestring -package QuickCheck -package test-framework \- -package test-framework-quickcheck -ignore-package text \+ -package bytestring -ignore-package text \ -fno-ignore-asserts+ghc-test-flags := -package QuickCheck -package test-framework \+ -package test-framework-quickcheck ghc-base-flags += -Wall -fno-warn-orphans -fno-warn-missing-signatures ghc-flags := $(ghc-base-flags) -i../dist/build -package-name text-$(version) ghc-hpc-flags := $(ghc-base-flags) -fhpc -fno-ignore-asserts -odir hpcdir \@@ -15,7 +16,7 @@ cabal := $(shell which cabal 2>/dev/null) -all: qc coverage+all: bm qc coverage lib: $(lib) @@ -28,6 +29,7 @@ cd .. && cabal build endif +Properties.o qc qc-hpc: ghc-flags += $(ghc-test-flags) Properties.o: QuickCheckUtils.o SlowFunctions.o QuickCheckUtils.o: $(lib)@@ -35,7 +37,7 @@ qc: Properties.o QuickCheckUtils.o SlowFunctions.o $(ghc) $(ghc-flags) -threaded -o $@ $^ $(lib) -sb: SearchBench.o+sb: SearchBench.o SlowFunctions.o $(ghc) $(ghc-flags) -threaded -o $@ $^ $(lib) qc-hpc: Properties.hs QuickCheckUtils.hs $(lib-srcs:%=../%)@@ -52,6 +54,12 @@ --exclude=Data.Text.Fusion.CaseMapping \ --exclude=QuickCheckUtils --srcdir=.. --srcdir=. --destdir=$(dir $@) +Benchmarks.o: ghc-opt-flags = -O+bm Benchmarks.o: ghc-flags += -hide-package transformers -package utf8-string+bm: Benchmarks.o+ $(ghc) $(ghc-flags) -o $@ $^ $(lib)++SlowFunctions.o: ghc-opt-flags = -O2 SearchBench.o: ghc-opt-flags = -O %.o: %.hs $(ghc) $(ghc-flags) $(ghc-opt-flags) -c -o $@ $<@@ -66,4 +74,4 @@ curl -O http://projects.haskell.org/text/text-testdata.tar.bz2 clean:- -rm -rf *.o *.hi *.tix qc qc-hpc hpcdir .hpc qc-hpc-html+ -rm -rf *.o *.hi *.tix bm qc qc-hpc hpcdir .hpc qc-hpc-html
text.cabal view
@@ -1,5 +1,5 @@ name: text-version: 0.5+version: 0.6 synopsis: An efficient packed Unicode text type description: An efficient packed Unicode text type. license: BSD3@@ -23,6 +23,7 @@ scripts/SpecialCasing.hs scripts/SpecialCasing.txt tests/Makefile+ tests/Benchmarks.hs tests/Properties.hs tests/QuickCheckUtils.hs tests/SlowFunctions.hs@@ -63,7 +64,8 @@ build-depends: base < 5,- bytestring >= 0.9 && < 1.0+ bytestring >= 0.9 && < 1.0,+ deepseq >= 1.1.0.0 if impl(ghc >= 6.10) build-depends: ghc-prim, base >= 4