@@ -1,4 +1,4 @@
1−{-# LANGUAGE BangPatterns #-}
1+{-# LANGUAGE BangPatterns, Rank2Types #-}
22-- |
33-- Module : Data.Text.Fusion.Common
44-- Copyright : (c) Bryan O'Sullivan 2009
@@ -37,6 +37,7 @@ module Data.Text.Fusion.Common
3737
3838 -- ** Case conversion
3939 , toUpper
40+ , toLower
4041
4142 -- * Folds
4243 , foldl
@@ -99,7 +100,7 @@ import Prelude (Bool(..), Char, Either(..), Eq(..), Int, Integral, Maybe(..),
99100import qualified Data.List as L
100101import qualified Prelude as P
101102import Data.Text.Fusion.Internal
102−import Data.Text.Fusion.CaseMapping (upperMapping)
103+import Data.Text.Fusion.CaseMapping (lowerMapping, upperMapping)
103104
104105singleton :: Char -> Stream Char
105106singleton c = Stream next False 1 -- HINT maybe too low
@@ -299,22 +300,34 @@ intersperse c (Stream next0 s0 len) = Stream next (s0 :!: N :!: S1) len -- HINT
299300-- ----------------------------------------------------------------------------
300301-- ** Case conversions (folds)
301302
302−-- | /O(n)/ Convert a string to upper case, using simple case
303−-- conversion. The result string may be longer than the input string.
304−-- For instance, the German eszett (U+00DF) maps to the two-letter
305−-- sequence SS.
306−toUpper :: Stream Char -> Stream Char
307−toUpper (Stream next0 s0 len) = Stream next (s0 :!: '\0' :!: '\0') len
303+caseConvert :: (forall s. Char -> s -> Step (PairS (PairS s Char) Char) Char)
304+ -> Stream Char -> Stream Char
305+caseConvert remap (Stream next0 s0 len) = Stream next (s0 :!: '\0' :!: '\0') len
308306 where
309307 {-# INLINE next #-}
310308 next (s :!: '\0' :!: _) =
311309 case next0 s of
312310 Done -> Done
313311 Skip s' -> Skip (s' :!: '\0' :!: '\0')
314− Yield c s' -> upperMapping c s'
312+ Yield c s' -> remap c s'
315313 next (s :!: a :!: b) = Yield a (s :!: b :!: '\0')
314+
315+-- | /O(n)/ Convert a string to upper case, using simple case
316+-- conversion. The result string may be longer than the input string.
317+-- For instance, the German eszett (U+00DF) maps to the two-letter
318+-- sequence SS.
319+toUpper :: Stream Char -> Stream Char
320+toUpper = caseConvert upperMapping
316321{-# INLINE [0] toUpper #-}
317322
323+-- | /O(n)/ Convert a string to lower case, using simple case
324+-- conversion. The result string may be longer than the input string.
325+-- For instance, the German eszett (U+00DF) maps to the two-letter
326+-- sequence SS.
327+toLower :: Stream Char -> Stream Char
328+toLower = caseConvert lowerMapping
329+{-# INLINE [0] toLower #-}
330+
318331-- ----------------------------------------------------------------------------
319332-- * Reducing Streams (folds)
320333