charset 0.0 → 0.1
raw patch · 5 files changed
+521/−461 lines, 5 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- Data.CharSet: UnicodeCategory :: String -> String -> CharSet -> String -> UnicodeCategory
- Data.CharSet: alpha :: CharSet
- Data.CharSet: alphaNum :: CharSet
- Data.CharSet: ascii :: CharSet
- Data.CharSet: asciiLower :: CharSet
- Data.CharSet: asciiUpper :: CharSet
- Data.CharSet: control :: CharSet
- Data.CharSet: data UnicodeCategory
- Data.CharSet: digit :: CharSet
- Data.CharSet: elem :: Char -> CharSet -> Bool
- Data.CharSet: latin1 :: CharSet
- Data.CharSet: letter :: CharSet
- Data.CharSet: lower :: CharSet
- Data.CharSet: mark :: CharSet
- Data.CharSet: notElem :: Char -> CharSet -> Bool
- Data.CharSet: number :: CharSet
- Data.CharSet: octDigit :: CharSet
- Data.CharSet: posixAscii :: Map String CharSet
- Data.CharSet: print :: CharSet
- Data.CharSet: punctuation :: CharSet
- Data.CharSet: separator :: CharSet
- Data.CharSet: space :: CharSet
- Data.CharSet: symbol :: CharSet
- Data.CharSet: toInteger :: CharSet -> Integer
- Data.CharSet: unicodeCategories :: [UnicodeCategory]
- Data.CharSet: upper :: CharSet
+ Data.CharSet: difference :: CharSet -> CharSet -> CharSet
+ Data.CharSet: filter :: (Char -> Bool) -> CharSet -> CharSet
+ Data.CharSet: fold :: (Char -> b -> b) -> b -> CharSet -> b
+ Data.CharSet: fromAscList :: String -> CharSet
+ Data.CharSet: fromCharSet :: CharSet -> (Bool, IntSet)
+ Data.CharSet: isSubsetOf :: CharSet -> CharSet -> Bool
+ Data.CharSet: map :: (Char -> Char) -> CharSet -> CharSet
+ Data.CharSet: notMember :: Char -> CharSet -> Bool
+ Data.CharSet: overlaps :: CharSet -> CharSet -> Bool
+ Data.CharSet: partition :: (Char -> Bool) -> CharSet -> (CharSet, CharSet)
+ Data.CharSet: range :: Char -> Char -> CharSet
+ Data.CharSet: toAscList :: CharSet -> String
+ Data.CharSet: toCharSet :: IntSet -> CharSet
+ Data.CharSet: toList :: CharSet -> String
+ Data.CharSet.Common: alpha :: CharSet
+ Data.CharSet.Common: alphaNum :: CharSet
+ Data.CharSet.Common: ascii :: CharSet
+ Data.CharSet.Common: asciiLower :: CharSet
+ Data.CharSet.Common: asciiUpper :: CharSet
+ Data.CharSet.Common: control :: CharSet
+ Data.CharSet.Common: digit :: CharSet
+ Data.CharSet.Common: latin1 :: CharSet
+ Data.CharSet.Common: letter :: CharSet
+ Data.CharSet.Common: lower :: CharSet
+ Data.CharSet.Common: mark :: CharSet
+ Data.CharSet.Common: number :: CharSet
+ Data.CharSet.Common: octDigit :: CharSet
+ Data.CharSet.Common: print :: CharSet
+ Data.CharSet.Common: punctuation :: CharSet
+ Data.CharSet.Common: separator :: CharSet
+ Data.CharSet.Common: space :: CharSet
+ Data.CharSet.Common: symbol :: CharSet
+ Data.CharSet.Common: upper :: CharSet
+ Data.CharSet.Posix.Ascii: alnum :: CharSet
+ Data.CharSet.Posix.Ascii: alpha :: CharSet
+ Data.CharSet.Posix.Ascii: blank :: CharSet
+ Data.CharSet.Posix.Ascii: cntrl :: CharSet
+ Data.CharSet.Posix.Ascii: digit :: CharSet
+ Data.CharSet.Posix.Ascii: graph :: CharSet
+ Data.CharSet.Posix.Ascii: lower :: CharSet
+ Data.CharSet.Posix.Ascii: posixAscii :: Map String CharSet
+ Data.CharSet.Posix.Ascii: print :: CharSet
+ Data.CharSet.Posix.Ascii: punct :: CharSet
+ Data.CharSet.Posix.Ascii: space :: CharSet
+ Data.CharSet.Posix.Ascii: upper :: CharSet
+ Data.CharSet.Posix.Ascii: word :: CharSet
+ Data.CharSet.Posix.Ascii: xdigit :: CharSet
+ Data.CharSet.Unicode: UnicodeCategory :: String -> String -> CharSet -> String -> UnicodeCategory
+ Data.CharSet.Unicode: closePunctuation :: CharSet
+ Data.CharSet.Unicode: connectorPunctuation :: CharSet
+ Data.CharSet.Unicode: control :: CharSet
+ Data.CharSet.Unicode: currencySymbol :: CharSet
+ Data.CharSet.Unicode: dashPunctuation :: CharSet
+ Data.CharSet.Unicode: data UnicodeCategory
+ Data.CharSet.Unicode: decimalNumber :: CharSet
+ Data.CharSet.Unicode: enclosingMark :: CharSet
+ Data.CharSet.Unicode: finalQuote :: CharSet
+ Data.CharSet.Unicode: format :: CharSet
+ Data.CharSet.Unicode: initialQuote :: CharSet
+ Data.CharSet.Unicode: instance Data UnicodeCategory
+ Data.CharSet.Unicode: instance Show UnicodeCategory
+ Data.CharSet.Unicode: instance Typeable UnicodeCategory
+ Data.CharSet.Unicode: letter :: CharSet
+ Data.CharSet.Unicode: letterAnd :: CharSet
+ Data.CharSet.Unicode: letterNumber :: CharSet
+ Data.CharSet.Unicode: lineSeparator :: CharSet
+ Data.CharSet.Unicode: lowercaseLetter :: CharSet
+ Data.CharSet.Unicode: mark :: CharSet
+ Data.CharSet.Unicode: mathSymbol :: CharSet
+ Data.CharSet.Unicode: modifierLetter :: CharSet
+ Data.CharSet.Unicode: modifierSymbol :: CharSet
+ Data.CharSet.Unicode: nonSpacingMark :: CharSet
+ Data.CharSet.Unicode: notAssigned :: CharSet
+ Data.CharSet.Unicode: number :: CharSet
+ Data.CharSet.Unicode: openPunctuation :: CharSet
+ Data.CharSet.Unicode: other :: CharSet
+ Data.CharSet.Unicode: otherLetter :: CharSet
+ Data.CharSet.Unicode: otherNumber :: CharSet
+ Data.CharSet.Unicode: otherPunctuation :: CharSet
+ Data.CharSet.Unicode: otherSymbol :: CharSet
+ Data.CharSet.Unicode: paragraphSeparator :: CharSet
+ Data.CharSet.Unicode: privateUse :: CharSet
+ Data.CharSet.Unicode: punctuation :: CharSet
+ Data.CharSet.Unicode: separator :: CharSet
+ Data.CharSet.Unicode: space :: CharSet
+ Data.CharSet.Unicode: spacingCombiningMark :: CharSet
+ Data.CharSet.Unicode: surrogate :: CharSet
+ Data.CharSet.Unicode: symbol :: CharSet
+ Data.CharSet.Unicode: titlecaseLetter :: CharSet
+ Data.CharSet.Unicode: unicodeCategories :: [UnicodeCategory]
+ Data.CharSet.Unicode: uppercaseLetter :: CharSet
- Data.CharSet: toArray :: CharSet -> Array Char Bool
+ Data.CharSet: toArray :: CharSet -> UArray Char Bool
Files
- Data/CharSet.hs +219/−458
- Data/CharSet/Common.hs +65/−0
- Data/CharSet/Posix/Ascii.hs +54/−0
- Data/CharSet/Unicode.hs +177/−0
- charset.cabal +6/−3
Data/CharSet.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE BangPatterns, CPP #-}+{-# LANGUAGE CPP #-} ----------------------------------------------------------------------------- -- | -- Module : Data.CharSet@@ -6,532 +6,240 @@ -- License : BSD3 -- Maintainer : ekmett@gmail.com -- Stability : experimental--- Portability : portable+-- Portability : portable (CPP) ----- Encode unicode character sets as arbitrary precision floating point values--- using the least character in the set as the exponent. Can efficiently represent--- reasonably tightly grouped character sets, but may use up to 139KiB to represent--- a particularly sparse set.--- +-- Fast complementable character sets+-- -- Designed to be imported qualified: -- -- > import Data.CharSet (CharSet) -- > import qualified Data.CharSet as CharSet ------------------------------------------------------------------------------- -module Data.CharSet+module Data.CharSet ( - -- * CharSet+ -- * Set type CharSet+ -- * Operators+ , (\\)+ -- * Query+ , null+ , size+ , member+ , notMember+ , overlaps, isSubsetOf+ , isComplemented + -- * Construction , build- -- * Manipulation , empty , singleton , full- , union- , intersection- , complement , insert , delete- , (\\)+ , complement+ , range+ -- * Combine+ , union+ , intersection+ , difference+ -- * Filter+ , filter+ , partition+ -- * Map+ , map+ -- * Fold+ , fold+ -- * Conversion+ -- ** List+ , toList , fromList+ -- ** Ordered list+ , toAscList+ , fromAscList , fromDistinctAscList+ -- ** IntMaps+ , fromCharSet+ , toCharSet+ -- ** Array , toArray- -- * Accessors- , null- , size- , member- , elem- , notElem- , isComplemented- , toInteger- -- * Builtins- -- ** POSIX- , posixAscii- -- ** Unicode- , UnicodeCategory(..)- , unicodeCategories- -- ** Data.Char classifiers- , control, space, lower, upper, alpha, alphaNum- , print, digit, octDigit, letter, mark, number- , punctuation, symbol, separator, ascii, latin1, asciiUpper, asciiLower ) where -import Data.Array hiding (range)-import qualified Data.Bits as Bits-import Data.Bits hiding (complement)-import Data.Char+import Data.Array.Unboxed hiding (range) import Data.Data import Data.Function (on)-import Data.Map (Map)-import qualified Data.Map as Map+import Data.IntSet (IntSet) import Data.Monoid (Monoid(..))-import Prelude hiding (null, exponent, toInteger, elem, notElem, print, pi)+import qualified Data.IntSet as I+import qualified Data.List as L+import Prelude hiding (filter, map, null)+import qualified Prelude as P import Text.Read -data CharSet = CS- { _countAtLeast :: {-# UNPACK #-} !Int -- ^ A conservative upper bound on the element count.- -- If negative, we are complemented with respect to the universe- , _countAtMost :: {-# UNPACK #-} !Int -- ^ A conservative lower bound on the element count.- -- If negative, we are complemented with respect to the universe- , _count :: Int -- ^ Lazy element count used when the above two disagree. O(1) environment size- , exponent :: {-# UNPACK #-} !Int -- ^ Low water mark. index of the least element potentially in the set.- , _hwm :: {-# UNPACK #-} !Int -- ^ High water mark. index of the greatest element potentially in the set.- , mantissa :: {-# UNPACK #-} !Integer -- ^ the set of bits starting from the exponent.- -- if negative, then we are complemented with respect to universe- }+data CharSet = P IntSet | N IntSet +(\\) :: CharSet -> CharSet -> CharSet+(\\) = difference -ul, uh :: Char-ul = minBound-uh = maxBound-{-# INLINE ul #-}-{-# INLINE uh #-}+build :: (Char -> Bool) -> CharSet+build p = fromDistinctAscList $ P.filter p [minBound .. maxBound]+{-# INLINE build #-} -ol, oh :: Int-ol = fromEnum ul-oh = fromEnum uh-{-# INLINE ol #-}-{-# INLINE oh #-}+map :: (Char -> Char) -> CharSet -> CharSet+map f (P i) = P (I.map (fromEnum . f . toEnum) i)+map f (N i) = fromList $ P.map f $ P.filter (\x -> fromEnum x `I.notMember` i) [ul..uh] +{-# INLINE map #-} --- | Internal smart constructor. Forces count whenever it is pigeonholed.-bs :: Int -> Int -> Int -> Int -> Int -> Integer -> CharSet-bs !a !b c !l !h !m | a == b = CS a a a l h m - | otherwise = CS a b c l h m -{-# INLINE bs #-}+isComplemented :: CharSet -> Bool+isComplemented (P _) = False+isComplemented (N _) = True+{-# INLINE isComplemented #-} --- | /O(d)/ where /d/ is absolute deviation in fromEnum over the set toList :: CharSet -> String-toList (CS _ _ _ l h m) - | m < 0 = map toEnum [ol..max (pred l) ol] ++ toList' l (map toEnum [min (succ h) oh..oh])- | otherwise = toList' 0 []- where- toList' :: Int -> String -> String- toList' !n t | n > h = t- | testBit m (n - l) = toEnum n : toList' (n+1) t- | otherwise = toList' (n+1) t+toList (P i) = P.map toEnum (I.toList i)+toList (N i) = P.filter (\x -> fromEnum x `I.notMember` i) [ul..uh] {-# INLINE toList #-} --- | /O(1)/ The empty set. Permits /O(1)/ null and size.+toAscList :: CharSet -> String+toAscList (P i) = P.map toEnum (I.toAscList i)+toAscList (N i) = P.filter (\x -> fromEnum x `I.notMember` i) [ul..uh]+{-# INLINE toAscList #-}+ empty :: CharSet-empty = CS 0 0 0 0 0 0 +empty = P I.empty {-# INLINE empty #-} --- | /O(1)/ Construct a @CharSet@ with a single element. Permits /O(1)/ null and size-singleton :: Char -> CharSet -singleton x = CS 1 1 1 e e 1 where e = fromEnum x+singleton :: Char -> CharSet+singleton = P . I.singleton . fromEnum {-# INLINE singleton #-} --- | /O(1|d)/ Is the 'CharSet' empty? May be faster than checking if @'size' == 0@ after union.--- Operations that require a recount are noted.+full :: CharSet+full = N I.empty+{-# INLINE full #-}+ null :: CharSet -> Bool-null (CS a b c _ _ _) - | a > 0 = False- | b == 0 = True- | otherwise = c == 0 +null (P i) = I.null i+null (N i) = I.size i == numChars -- badly normalized! {-# INLINE null #-} --- | /O(1|d)/ The number of elements in the bit set. size :: CharSet -> Int-size (CS a b c _ _ m)- | (a == b) && (m >= 0) = a- | a == b = oh - ol - a - | m >= 0 = c- | otherwise = oh - ol - c +size (P i) = I.size i+size (N i) = numChars - I.size i {-# INLINE size #-} --- | /O(d)/ A 'CharSet' containing every member of the enumeration of @a@.-full :: CharSet-full = complement empty -{-# INLINE full #-}---- | /O(d)/ Complements a 'CharSet' with respect to the bounds of @a@. Preserves order of 'null' and 'size'-complement :: CharSet -> CharSet -complement (CS a b c l h m) = CS (Bits.complement b) (Bits.complement a) (Bits.complement c) l h (Bits.complement m)-{-# INLINE complement #-}---- | /O(d * n)/ Make a 'CharSet' from a list of items.-fromList :: String -> CharSet-fromList = foldr insert empty -{-# INLINE fromList #-}---- | /O(d * n)/ Make a 'CharSet' from a distinct ascending list of items-fromDistinctAscList :: String -> CharSet -fromDistinctAscList [] = empty-fromDistinctAscList (c:cs) = fromDistinctAscList' cs 1 0 1 - where- l = fromEnum c- fromDistinctAscList' :: String -> Int -> Int -> Integer -> CharSet- fromDistinctAscList' [] !n !h !m = CS n n n l h m - fromDistinctAscList' (c':cs') !n _ !m = fromDistinctAscList' cs' (n+1) h' (setBit m (h' - l))- where- h' = fromEnum c'-{-# INLINE fromDistinctAscList #-}---- | /O(d)/ Insert a single element of type @a@ into the 'CharSet'. Preserves order of 'null' and 'size' insert :: Char -> CharSet -> CharSet-insert x r@(CS a b c l h m) - | (m < 0) && (e < l) = r - | (m < 0) && (e > h) = r- | e < l = bs (a+1) (b+1) (c+1) e h (shiftL m (l - e) .|. 1)- | e > h = bs (a+1) (b+1) (c+1) l p (setBit m p)- | testBit m p = r - | otherwise = bs (a+1) (b+1) (c+1) l h (setBit m p)- where - e = fromEnum x- p = e - l +insert c (P i) = P (I.insert (fromEnum c) i)+insert c (N i) = P (I.delete (fromEnum c) i) {-# INLINE insert #-} --- | /O(d)/ Delete a single item from the 'CharSet'. Preserves order of 'null' and 'size'+range :: Char -> Char -> CharSet+range a b + | a <= b = fromDistinctAscList [a..b]+ | otherwise = empty+ delete :: Char -> CharSet -> CharSet-delete x r@(CS a b c l h m) - | (m < 0) && (e < l) = bs (a+1) (b+1) (c+1) e h (shiftL m (l - e) .&. Bits.complement 1)- | (m < 0) && (e > h) = bs (a+1) (b+1) (c+1) l p (clearBit m p)- | e < l = r- | e > h = r- | testBit m p = bs (a-1) (b-1) (c-1) l h (clearBit m p)- | otherwise = r- where - e = fromEnum x- p = e - l+delete c (P i) = P (I.delete (fromEnum c) i)+delete c (N i) = N (I.insert (fromEnum c) i) {-# INLINE delete #-} --- | /O(1)/ Test for membership in a 'CharSet'-member :: Char -> CharSet -> Bool-member x (CS _ _ _ l h m) - | e < l = m < 0 - | e > h = m > 0- | otherwise = testBit m (e - l)- where - e = fromEnum x-{-# INLINE member #-}--{--notMember :: Char -> CharSet -> Bool-notMember x - not . member x-{-# INLINE notMember #-}--}---- | /O(1)/ Alias for member-elem :: Char -> CharSet -> Bool-elem = member-{-# INLINE elem #-}---- | /O(1)/ Alias for notMember-notElem :: Char -> CharSet -> Bool-notElem x = not . elem x-{-# INLINE notElem #-}---- | /O(d)/ convert to an Integer representation. Discards negative elements-toInteger :: CharSet -> Integer-toInteger x = mantissa x `shift` exponent x-{-# INLINE toInteger #-}+complement :: CharSet -> CharSet+complement (P i) = N i+complement (N i) = P i+{-# INLINE complement #-} --- | /O(d)/. May force 'size' to take /O(d)/ if ranges overlap, preserves order of 'null'-union :: CharSet -> CharSet -> CharSet -union x@(CS _ _ _ l _ _) y@(CS _ _ _ l' _ _)- | l' < l = union' y x -- ensure left side has lower exponent- | otherwise = union' x y +union :: CharSet -> CharSet -> CharSet+union (P i) (P j) = P (I.union i j)+union (P i) (N j) = N (I.difference j i)+union (N i) (P j) = N (I.difference i j)+union (N i) (N j) = N (I.intersection i j) {-# INLINE union #-} -union' :: CharSet -> CharSet -> CharSet -union' x@(CS a b c l h m) y@(CS a' b' c' l' h' m')- | b == 0 = y -- fast empty union- | b' == 0 = x -- fast empty union- | a == -1 = full -- fast full union- | a' == -1 = full -- fast full union- | (m < 0) && (m' < 0) = complement (intersection' (complement x) (complement y)) -- appeal to intersection- | m' < 0 = complement (diff (complement y) x) -- union with complement- | m < 0 = complement (diff (complement x) y) -- union with complement- | h < l' = bs (a + a') (b + b') (c + c') l h' m'' -- disjoint positive ranges- | otherwise = bs (a `max` a') (b + b') (recount m'') l (h `max` h') m'' -- overlapped positives- where - m'' = m .|. shiftL m' (l' - l)---- | /O(1)/ check to see if we are represented as a complemented 'CharSet'. -isComplemented :: CharSet -> Bool-isComplemented = (<0) . mantissa -{-# INLINE isComplemented #-}---- | /O(d)/. May force 'size' and 'null' both to take /O(d)/.-intersection :: CharSet -> CharSet -> CharSet -intersection x@(CS _ _ _ l _ _) y@(CS _ _ _ l' _ _)- | l' < l = intersection' y x- | otherwise = intersection' x y+intersection :: CharSet -> CharSet -> CharSet+intersection (P i) (P j) = P (I.intersection i j)+intersection (P i) (N j) = P (I.difference i j)+intersection (N i) (P j) = P (I.difference j i)+intersection (N i) (N j) = N (I.union i j) {-# INLINE intersection #-} --- | /O(d)/. May force 'size' and 'null' both to take /O(d)/.-intersection' :: CharSet -> CharSet -> CharSet -intersection' x@(CS a b _ l h m) y@(CS a' b' _ l' h' m')- | b == 0 = empty- | b' == 0 = empty- | a == -1 = y- | a' == -1 = x- | (m < 0) && (m' < 0) = complement (union' (complement x) (complement y))- | m' < 0 = diff x (complement y) - | m < 0 = diff y (complement x) - | h < l' = empty - | otherwise = bs 0 (b `min` b') (recount m'') l'' (h `min` h') m''- where- l'' = max l l'- m'' = shift m (l'' - l) .&. shift m' (l'' - l')---- | Unsafe internal method for computing differences --- preconditions:--- m >= 0, m' >= 0, a /= -1, a' /= -1, b /= 0, b' /= 0-diff :: CharSet -> CharSet -> CharSet -diff x@(CS a _ _ l h m) (CS _ b' _ l' h' m') - | h < l' = x- | h' < l = x- | otherwise = bs (max (a - b') 0) a (recount m'') l h m''- where - m'' = m .&. shift (Bits.complement m') (l' - l)---- | /O(d)/. Preserves order of 'null'. May force /O(d)/ 'size'. difference :: CharSet -> CharSet -> CharSet -difference x@(CS a b _ _ _ m) y@(CS a' b' _ _ _ m') - | a == -1 = complement y- | a' == -1 = empty- | b == 0 = empty- | b' == 0 = x- | (m < 0) && (m' < 0) = diff (complement y) (complement x)- | m < 0 = complement (complement x `union` y)- | m' < 0 = x `union` complement y - | otherwise = diff x y- --- | /O(d)/. Preserves order of 'null'. May force /O(d)/ 'size'.-(\\) :: CharSet -> CharSet -> CharSet -(\\) = difference--instance Eq CharSet where- x@(CS _ _ _ l _ m) == y@(CS _ _ _ l' _ m')- | signum m == signum m' = shift m (l - l'') == shift m' (l - l'') - | m' < 0 = y == x- | otherwise = mask .&. shift m (l - ol) == shift m' (l - ol)- where - l'' = min l l'- mask = setBit 0 (oh - ol + 1) - 1+difference (P i) (P j) = P (I.difference i j)+difference (P i) (N j) = P (I.intersection i j)+difference (N i) (P j) = N (I.union i j)+difference (N i) (N j) = P (I.difference j i)+{-# INLINE difference #-} -instance Ord CharSet where- compare = compare `on` toInteger+member :: Char -> CharSet -> Bool+member c (P i) = I.member (fromEnum c) i+member c (N i) = I.notMember (fromEnum c) i+{-# INLINE member #-} -instance Bounded CharSet where- minBound = empty- maxBound = CS n n n ol oh m- where- n = oh - ol + 1- m = setBit 0 n - 1+notMember :: Char -> CharSet -> Bool+notMember c (P i) = I.notMember (fromEnum c) i+notMember c (N i) = I.member (fromEnum c) i+{-# INLINE notMember #-} --- | Return a charset based on a character range-range :: Char -> Char -> CharSet-range l h - | l <= h = CS n n n l' h' m- | otherwise = empty- where - l' = fromEnum l- h' = fromEnum h- n = h' - l' + 1- m = setBit 0 n - 1+fold :: (Char -> b -> b) -> b -> CharSet -> b+fold f z (P i) = I.fold (f . toEnum) z i+fold f z (N i) = foldr f z $ P.filter (\x -> fromEnum x `I.notMember` i) [ul..uh]+{-# INLINE fold #-} --- | /O(d)/-recount :: Integer -> Int-recount !n - | n < 0 = Bits.complement (recount (Bits.complement n))- | otherwise = recount' 0 0 - where- h = hwm n- recount' !i !c- | i > h = c- | otherwise = recount' (i+1) (if testBit n i then c+1 else c)+filter :: (Char -> Bool) -> CharSet -> CharSet +filter p (P i) = P (I.filter (p . toEnum) i)+filter p (N i) = N $ foldr (I.insert) i $ P.filter (\x -> (x `I.notMember` i) && not (p (toEnum x))) [ol..oh]+{-# INLINE filter #-} --- | /O(d)/. Computes the equivalent of (truncate . logBase 2 . abs) extended with 0 at 0--- This could be computed faster by directly appealing to GMP, but that is tricky in GHC.-hwm :: Integer -> Int-hwm !n - | n < 0 = hwm (-n)- | n > 1 = scan p (2*p) - | otherwise = 0- where- p = probe 1- -- incrementally compute 2^(2^(i+1)) until it exceeds n- probe :: Int -> Int- probe !i- | bit (2*i) > n = i- | otherwise = probe (2*i)+partition :: (Char -> Bool) -> CharSet -> (CharSet, CharSet)+partition p (P i) = (P l, P r)+ where (l,r) = I.partition (p . toEnum) i+partition p (N i) = (N (foldr I.insert i l), N (foldr I.insert i r))+ where (l,r) = L.partition (p . toEnum) $ P.filter (\x -> x `I.notMember` i) [ol..oh]+{-# INLINE partition #-} - -- then binary search the powers for the highest set bit- scan :: Int -> Int -> Int- scan !l !h- | l == h = l- | bit (m+1) > n = scan l m- | otherwise = scan (m+1) h- where m = l + (h - l) `div` 2+overlaps :: CharSet -> CharSet -> Bool+overlaps (P i) (P j) = not (I.null (I.intersection i j))+overlaps (P i) (N j) = not (I.isSubsetOf j i)+overlaps (N i) (P j) = not (I.isSubsetOf i j)+overlaps (N i) (N j) = any (\x -> I.notMember x i && I.notMember x j) [ol..oh] -- not likely+{-# INLINE overlaps #-} -toArray :: CharSet -> Array Char Bool-toArray set = array (minBound, maxBound) $ fmap (\x -> (x, x `elem` set)) [minBound .. maxBound]- -instance Show CharSet where- showsPrec d x@(CS _ _ _ _ _ m)- | m < 0 = showParen (d > 10) $ showString "complement " . showsPrec 11 (complement x)- | otherwise = showParen (d > 10) $ showString "fromDistinctAscList " . showsPrec 11 (toList x)+isSubsetOf :: CharSet -> CharSet -> Bool+isSubsetOf (P i) (P j) = I.isSubsetOf i j+isSubsetOf (P i) (N j) = I.null (I.intersection i j)+isSubsetOf (N i) (P j) = all (\x -> I.member x i && I.member x j) [ol..oh]-- not bloody likely+isSubsetOf (N i) (N j) = I.isSubsetOf j i+{-# INLINE isSubsetOf #-} +fromList :: String -> CharSet +fromList = P . I.fromList . P.map fromEnum+{-# INLINE fromList #-} -instance Read CharSet where-#ifdef __GLASGOW_HASKELL__ - readPrec = parens $ complemented +++ normal - where- complemented = prec 10 $ do - Ident "complement" <- lexP- complement `fmap` step readPrec- normal = prec 10 $ do- Ident "fromDistinctAscList" <- lexP- fromDistinctAscList `fmap` step readPrec-#else- readsPrec d r = - readParen (d > 10) (\r -> [ (complement m, t) - | ("complement", s) <- lex r- , (m, t) <- readsPrec 11 s]) r- ++ readParen (d > 10) (\r -> [ (fromDistinctAscList m, t) - | ("fromDistinctAscList", s) <- lex r- , (m, t) <- readsPrec 11 s]) r-#endif+fromAscList :: String -> CharSet+fromAscList = P . I.fromAscList . P.map fromEnum+{-# INLINE fromAscList #-} -instance Monoid CharSet where- mempty = empty- mappend = union+fromDistinctAscList :: String -> CharSet+fromDistinctAscList = P . I.fromDistinctAscList . P.map fromEnum+{-# INLINE fromDistinctAscList #-} -build :: (Char -> Bool) -> CharSet-build p = fromDistinctAscList $ filter p [minBound .. maxBound]+-- isProperSubsetOf :: CharSet -> CharSet -> Bool+-- isProperSubsetOf (P i) (P j) = I.isProperSubsetOf i j+-- isProperSubsetOf (P i) (N j) = null (I.intersection i j) && ...+-- isProperSubsetOf (N i) (N j) = I.isProperSubsetOf j i --- :digit:, etc.-posixAscii :: Map String CharSet-posixAscii = Map.fromList- [ ("alnum", alnum')- , ("alpha", alpha')- , ("blank", fromList " \t")- , ("cntrl", insert '\x7f' $ range '\x00' '\x1f')- , ("digit", digit')- , ("graph", range '\x21' '\x7e')- , ("print", range '\x20' '\x7e')- , ("word", insert '_' alnum')- , ("punct", fromList "-!\"#$%&'()*+,./:;<=>?@[\\]^_`{|}~")- , ("space", fromList " \t\r\n\v\f")- , ("upper", upper')- , ("lower", lower')- , ("xdigit", digit `union` range 'a' 'f' `union` range 'A' 'F')- ]- where- lower' = range 'a' 'z'- upper' = range 'A' 'Z'- alpha' = lower' `union` upper'- digit' = range '0' '9'- alnum' = alpha' `union` digit'+ul, uh :: Char+ul = minBound+uh = maxBound+{-# INLINE ul #-}+{-# INLINE uh #-} -data UnicodeCategory = UnicodeCategory String String CharSet String+ol, oh :: Int+ol = fromEnum ul+oh = fromEnum uh+{-# INLINE ol #-}+{-# INLINE oh #-} --- \p{Letter} or \p{Mc}-unicodeCategories :: [UnicodeCategory]-unicodeCategories =- [ UnicodeCategory "Letter" "L" l "any kind of letter from any language."- , UnicodeCategory "Lowercase_Letter" "Ll" ll "a lowercase letter that has an uppercase variant"- , UnicodeCategory "Uppercase_Letter" "Lu" lu "an uppercase letter that has a lowercase variant"- , UnicodeCategory "Titlecase_Letter" "Lt" lt "a letter that appears at the start of a word when only the first letter of the word is capitalized"- , UnicodeCategory "Letter&" "L&" la "a letter that exists in lowercase and uppercase variants (combination of Ll, Lu and Lt)"- , UnicodeCategory "Modifier_Letter" "Lm" lm "a special character that is used like a letter"- , UnicodeCategory "Other_Letter" "Lo" lo "a letter or ideograph that does not have lowercase and uppercase variants"- , UnicodeCategory "Mark" "M" m "a character intended to be combined with another character (e.g. accents, umlauts, enclosing boxes, etc.)"- , UnicodeCategory "Non_Spacing_Mark" "Mn" mn "a character intended to be combined with another character without taking up extra space (e.g. accents, umlauts, etc.)"- , UnicodeCategory "Spacing_Combining_Mark" "Mc" mc "a character intended to be combined with another character that takes up extra space (vowel signs in many Eastern languages)"- , UnicodeCategory "Enclosing_Mark" "Me" me "a character that encloses the character is is combined with (circle, square, keycap, etc.)"- , UnicodeCategory "Separator" "Z" z "any kind of whitespace or invisible separator"- , UnicodeCategory "Space_Separator" "Zs" zs "a whitespace character that is invisible, but does take up space"- , UnicodeCategory "Line_Separator" "Zl" zl "line separator character U+2028"- , UnicodeCategory "Paragraph_Separator" "Zp" zp "paragraph separator character U+2029"- , UnicodeCategory "Symbol" "S" s "math symbols, currency signs, dingbats, box-drawing characters, etc."- , UnicodeCategory "Math_Symbol" "Sm" sm "any mathematical symbol"- , UnicodeCategory "Currency_Symbol" "Sc" sc "any currency sign"- , UnicodeCategory "Modifier_Symbol" "Sk" sk "a combining character (mark) as a full character on its own"- , UnicodeCategory "Other_Symbol" "So" so "various symbols that are not math symbols, currency signs, or combining characters"- , UnicodeCategory "Number" "N" n "any kind of numeric character in any script"- , UnicodeCategory "Decimal_Digit_Number" "Nd" nd "a digit zero through nine in any script except ideographic scripts"- , UnicodeCategory "Letter_Number" "Nl" nl "a number that looks like a letter, such as a Roman numeral"- , UnicodeCategory "Other_Number" "No" no "a superscript or subscript digit, or a number that is not a digit 0..9 (excluding numbers from ideographic scripts)"- , UnicodeCategory "Punctuation" "P" p "any kind of punctuation character"- , UnicodeCategory "Dash_Punctuation" "Pd" pd "any kind of hyphen or dash"- , UnicodeCategory "Open_Punctuation" "Ps" ps "any kind of opening bracket"- , UnicodeCategory "Close_Punctuation" "Pe" pe "any kind of closing bracket"- , UnicodeCategory "Initial_Punctuation" "Pi" pi "any kind of opening quote"- , UnicodeCategory "Final_Punctuation" "Pf" pf "any kind of closing quote"- , UnicodeCategory "Connector_Punctuation" "Pc" pc "a punctuation character such as an underscore that connects words"- , UnicodeCategory "Other_Punctuation" "Po" po "any kind of punctuation character that is not a dash, bracket, quote or connector"- , UnicodeCategory "Other" "C" c "invisible control characters and unused code points"- , UnicodeCategory "Control" "Cc" cc "an ASCII 0x00..0x1F or Latin-1 0x80..0x9F control character"- , UnicodeCategory "Format" "Cf" cf "invisible formatting indicator"- , UnicodeCategory "Private_Use" "Co" co "any code point reserved for private use"- , UnicodeCategory "Surrogate" "Cs" cs "one half of a surrogate pair in UTF-16 encoding"- , UnicodeCategory "Unassigned" "Cn" cn "any code point to which no character has been assigned.properties" ]- where- cat category = build ((category ==) . generalCategory)- ll = cat LowercaseLetter- lu = cat UppercaseLetter- lt = cat TitlecaseLetter- la = ll `union` lu `union` lt- lm = cat ModifierLetter- lo = cat OtherLetter- l = la `union` lm `union` lo- mn = cat NonSpacingMark- mc = cat SpacingCombiningMark- me = cat EnclosingMark- m = mn `union` mc `union` me- zs = cat Space- zl = cat LineSeparator- zp = cat ParagraphSeparator- z = zs `union` zl `union` zp- sm = cat MathSymbol- sc = cat CurrencySymbol- sk = cat ModifierSymbol- so = cat OtherSymbol- s = sm `union` sc `union` sk `union` so- nd = cat DecimalNumber- nl = cat LetterNumber- no = cat OtherNumber- n = nd `union` nl `union` no- pd = cat DashPunctuation- ps = cat OpenPunctuation- pe = cat ClosePunctuation- pi = cat InitialQuote- pf = cat FinalQuote- pc = cat ConnectorPunctuation- po = cat OtherPunctuation- p = pd `union` ps `union` pe `union` pi `union` pf `union` pc `union` po- cc = cat Control- cf = cat Format- co = cat PrivateUse- cs = cat Surrogate- cn = cat NotAssigned- c = cc `union` cf `union` co `union` cs `union` cn- --- Haskell character classes from Data.Char-control, space, lower, upper, alpha, alphaNum, print, digit, octDigit, letter, mark, number, punctuation, symbol, separator, ascii, latin1, asciiUpper, asciiLower :: CharSet-control = build isControl-space = build isSpace-lower = build isLower-upper = build isUpper-alpha = build isAlpha-alphaNum = build isAlphaNum-print = build isPrint-digit = build isDigit-octDigit = build isOctDigit-letter = build isLetter-mark = build isMark-number = build isNumber-punctuation = build isPunctuation-symbol = build isSymbol-separator = build isSeparator-ascii = build isAscii-latin1 = build isLatin1-asciiUpper = build isAsciiUpper-asciiLower = build isAsciiLower+numChars :: Int+numChars = oh - ol + 1+{-# INLINE numChars #-} instance Typeable CharSet where typeOf _ = mkTyConApp charSetTyCon []@@ -543,6 +251,7 @@ instance Data CharSet where gfoldl k z set | isComplemented set = z complement `k` complement set | otherwise = z fromList `k` toList set+ toConstr set | isComplemented set = complementConstr | otherwise = fromListConstr@@ -553,7 +262,7 @@ 1 -> k (z fromList) 2 -> k (z complement) _ -> error "gunfold"- + fromListConstr :: Constr fromListConstr = mkConstr charSetDataType "fromList" [] Prefix {-# NOINLINE fromListConstr #-}@@ -565,3 +274,55 @@ charSetDataType :: DataType charSetDataType = mkDataType "Data.CharSet.CharSet" [fromListConstr, complementConstr] {-# NOINLINE charSetDataType #-}++-- returns an intset and if the intset should be complemented to obtain the contents of the CharSet+fromCharSet :: CharSet -> (Bool, IntSet)+fromCharSet (P i) = (False, i)+fromCharSet (N i) = (True, i) +{-# INLINE fromCharSet #-}++toCharSet :: IntSet -> CharSet+toCharSet = P+{-# INLINE toCharSet #-}++instance Eq CharSet where+ (==) = (==) `on` toAscList++instance Ord CharSet where+ compare = compare `on` toAscList++instance Bounded CharSet where+ minBound = empty+ maxBound = full++toArray :: CharSet -> UArray Char Bool+toArray set = array (minBound, maxBound) $ fmap (\x -> (x, x `member` set)) [minBound .. maxBound]+ +instance Show CharSet where+ showsPrec d i+ | isComplemented i = showParen (d > 10) $ showString "complement " . showsPrec 11 (complement i)+ | otherwise = showParen (d > 10) $ showString "fromDistinctAscList " . showsPrec 11 (toAscList i)++instance Read CharSet where+#ifdef __GLASGOW_HASKELL__ + readPrec = parens $ complemented +++ normal + where+ complemented = prec 10 $ do + Ident "complement" <- lexP+ complement `fmap` step readPrec+ normal = prec 10 $ do+ Ident "fromDistinctAscList" <- lexP+ fromDistinctAscList `fmap` step readPrec+#else+ readsPrec d r = + readParen (d > 10) (\r -> [ (complement m, t) + | ("complement", s) <- lex r+ , (m, t) <- readsPrec 11 s]) r+ ++ readParen (d > 10) (\r -> [ (fromDistinctAscList m, t) + | ("fromDistinctAscList", s) <- lex r+ , (m, t) <- readsPrec 11 s]) r+#endif++instance Monoid CharSet where+ mempty = empty+ mappend = union
+ Data/CharSet/Common.hs view
@@ -0,0 +1,65 @@+-----------------------------------------------------------------------------+-- |+-- Module : Data.CharSet.Common+-- Copyright : (c) Edward Kmett 2010+-- License : BSD3+-- Maintainer : ekmett@gmail.com+-- Stability : experimental+-- Portability : portable+--+-- The various character classifications from "Data.Char" as 'CharSet's+-------------------------------------------------------------------------------++module Data.CharSet.Common+ ( + -- ** Data.Char classes+ control+ , space+ , lower+ , upper+ , alpha+ , alphaNum+ , print+ , digit+ , octDigit+ , letter+ , mark+ , number+ , punctuation+ , symbol+ , separator+ , ascii+ , latin1+ , asciiUpper+ , asciiLower+ ) where++import Prelude ()+import Data.Char+import Data.CharSet++-- Haskell character classes from Data.Char+control, space, lower, upper, alpha, alphaNum, + print, digit, octDigit, letter, mark, number, + punctuation, symbol, separator, ascii, latin1+ , asciiUpper, asciiLower :: CharSet++control = build isControl+space = build isSpace+lower = build isLower+upper = build isUpper+alpha = build isAlpha+alphaNum = build isAlphaNum+print = build isPrint+digit = build isDigit+octDigit = build isOctDigit+letter = build isLetter+mark = build isMark+number = build isNumber+punctuation = build isPunctuation+symbol = build isSymbol+separator = build isSeparator+ascii = build isAscii+latin1 = build isLatin1+asciiUpper = build isAsciiUpper+asciiLower = build isAsciiLower
+ Data/CharSet/Posix/Ascii.hs view
@@ -0,0 +1,54 @@+-----------------------------------------------------------------------------+-- |+-- Module : Data.CharSet.Posix.Ascii+-- Copyright : (c) Edward Kmett 2010+-- License : BSD3+-- Maintainer : ekmett@gmail.com+-- Stability : experimental+-- Portability : portable+--+-------------------------------------------------------------------------------++module Data.CharSet.Posix.Ascii+ ( posixAscii+ -- * POSIX ASCII \"classes\"+ , alnum, alpha, blank, cntrl, digit, graph, print, word, punct, space, upper, lower, xdigit+ ) where++import Prelude hiding (print)+import Data.CharSet+import Data.Map (Map)+import qualified Data.Map as Map++alnum, alpha, blank, cntrl, digit, graph, print, word, punct, space, upper, lower, xdigit :: CharSet+alnum = alpha `union` digit+alpha = lower `union` upper+blank = fromList " \t"+cntrl = insert '\x7f' $ range '\x00' '\x1f'+digit = range '0' '9'+lower = range 'a' 'z'+upper = range 'A' 'Z'+graph = range '\x21' '\x7e'+print = insert '\x20' graph+word = insert '_' alnum+punct = fromList "-!\"#$%&'()*+,./:;<=>?@[\\]^_`{|}~"+space = fromList " \t\r\n\v\f"+xdigit = digit `union` range 'a' 'f' `union` range 'A' 'F'++-- :digit:, etc.+posixAscii :: Map String CharSet+posixAscii = Map.fromList+ [ ("alnum", alnum)+ , ("alpha", alpha)+ , ("blank", blank)+ , ("cntrl", cntrl)+ , ("digit", digit)+ , ("graph", graph) + , ("print", print)+ , ("word", word)+ , ("punct", punct)+ , ("space", space)+ , ("upper", upper)+ , ("lower", lower)+ , ("xdigit", xdigit)+ ]
+ Data/CharSet/Unicode.hs view
@@ -0,0 +1,177 @@+{-# LANGUAGE DeriveDataTypeable #-}+-----------------------------------------------------------------------------+-- |+-- Module : Data.CharSet.Unicode+-- Copyright : (c) Edward Kmett 2010+-- License : BSD3+-- Maintainer : ekmett@gmail.com+-- Stability : experimental+-- Portability : portable+--+-- Provides unicode general categories, which are typically connoted by +-- @\p{Ll}@ or @\p{Modifier_Letter}@. Lookups can be constructed using 'categories'+-- or individual character sets can be used directly.+-------------------------------------------------------------------------------++module Data.CharSet.Unicode+ ( + -- * Unicode General Category+ UnicodeCategory(..)+ -- * Lookup+ , unicodeCategories+ -- * CharSets by UnicodeCategory+ -- ** Letter+ , modifierLetter, otherLetter, letter+ -- *** Letter\&+ , lowercaseLetter, uppercaseLetter, titlecaseLetter, letterAnd+ -- ** Mark+ , nonSpacingMark, spacingCombiningMark, enclosingMark, mark+ -- ** Separator+ , space, lineSeparator, paragraphSeparator, separator+ -- ** Symbol+ , mathSymbol, currencySymbol, modifierSymbol, otherSymbol, symbol+ -- ** Number+ , decimalNumber, letterNumber, otherNumber, number+ -- ** Punctuation+ , dashPunctuation, openPunctuation, closePunctuation, initialQuote+ , finalQuote, connectorPunctuation, otherPunctuation, punctuation + -- ** Other+ , control, format, privateUse, surrogate, notAssigned, other+ ) where++import Data.Char+import Data.CharSet+import Data.Data++data UnicodeCategory = UnicodeCategory String String CharSet String+ deriving (Show, Data, Typeable)++-- \p{Letter} or \p{Mc}+unicodeCategories :: [UnicodeCategory]+unicodeCategories =+ [ UnicodeCategory "Letter" "L" letter "any kind of letter from any language."+ , UnicodeCategory "Lowercase_Letter" "Ll" lowercaseLetter "a lowercase letter that has an uppercase variant"+ , UnicodeCategory "Uppercase_Letter" "Lu" uppercaseLetter "an uppercase letter that has a lowercase variant"+ , UnicodeCategory "Titlecase_Letter" "Lt" titlecaseLetter "a letter that appears at the start of a word when only the first letter of the word is capitalized"+ , UnicodeCategory "Letter&" "L&" letterAnd "a letter that exists in lowercase and uppercase variants (combination of Ll, Lu and Lt)"+ , UnicodeCategory "Modifier_Letter" "Lm" modifierLetter "a special character that is used like a letter"+ , UnicodeCategory "Other_Letter" "Lo" otherLetter "a letter or ideograph that does not have lowercase and uppercase variants"+ , UnicodeCategory "Mark" "M" mark "a character intended to be combined with another character (e.g. accents, umlauts, enclosing boxes, etc.)"+ , UnicodeCategory "Non_Spacing_Mark" "Mn" nonSpacingMark "a character intended to be combined with another character without taking up extra space (e.g. accents, umlauts, etc.)"+ , UnicodeCategory "Spacing_Combining_Mark" "Mc" spacingCombiningMark "a character intended to be combined with another character that takes up extra space (vowel signs in many Eastern languages)"+ , UnicodeCategory "Enclosing_Mark" "Me" enclosingMark "a character that encloses the character is is combined with (circle, square, keycap, etc.)"+ , UnicodeCategory "Separator" "Z" separator "any kind of whitespace or invisible separator"+ , UnicodeCategory "Space_Separator" "Zs" space "a whitespace character that is invisible, but does take up space"+ , UnicodeCategory "Line_Separator" "Zl" lineSeparator "line separator character U+2028"+ , UnicodeCategory "Paragraph_Separator" "Zp" paragraphSeparator "paragraph separator character U+2029"+ , UnicodeCategory "Symbol" "S" symbol "math symbols, currency signs, dingbats, box-drawing characters, etc."+ , UnicodeCategory "Math_Symbol" "Sm" mathSymbol "any mathematical symbol"+ , UnicodeCategory "Currency_Symbol" "Sc" currencySymbol "any currency sign"+ , UnicodeCategory "Modifier_Symbol" "Sk" modifierSymbol "a combining character (mark) as a full character on its own"+ , UnicodeCategory "Other_Symbol" "So" otherSymbol "various symbols that are not math symbols, currency signs, or combining characters"+ , UnicodeCategory "Number" "N" number "any kind of numeric character in any script"+ , UnicodeCategory "Decimal_Digit_Number" "Nd" decimalNumber "a digit zero through nine in any script except ideographic scripts"+ , UnicodeCategory "Letter_Number" "Nl" letterNumber "a number that looks like a letter, such as a Roman numeral"+ , UnicodeCategory "Other_Number" "No" otherNumber "a superscript or subscript digit, or a number that is not a digit 0..9 (excluding numbers from ideographic scripts)"+ , UnicodeCategory "Punctuation" "P" punctuation "any kind of punctuation character"+ , UnicodeCategory "Dash_Punctuation" "Pd" dashPunctuation "any kind of hyphen or dash"+ , UnicodeCategory "Open_Punctuation" "Ps" openPunctuation "any kind of opening bracket"+ , UnicodeCategory "Close_Punctuation" "Pe" closePunctuation "any kind of closing bracket"+ , UnicodeCategory "Initial_Punctuation" "Pi" initialQuote "any kind of opening quote"+ , UnicodeCategory "Final_Punctuation" "Pf" finalQuote "any kind of closing quote"+ , UnicodeCategory "Connector_Punctuation" "Pc" connectorPunctuation "a punctuation character such as an underscore that connects words"+ , UnicodeCategory "Other_Punctuation" "Po" otherPunctuation "any kind of punctuation character that is not a dash, bracket, quote or connector"+ , UnicodeCategory "Other" "C" other "invisible control characters and unused code points"+ , UnicodeCategory "Control" "Cc" control "an ASCII 0x00..0x1F or Latin-1 0x80..0x9F control character"+ , UnicodeCategory "Format" "Cf" format "invisible formatting indicator"+ , UnicodeCategory "Private_Use" "Co" privateUse "any code point reserved for private use"+ , UnicodeCategory "Surrogate" "Cs" surrogate "one half of a surrogate pair in UTF-16 encoding"+ , UnicodeCategory "Unassigned" "Cn" notAssigned "any code point to which no character has been assigned.properties" ]++cat :: GeneralCategory -> CharSet+cat category = build ((category ==) . generalCategory)++-- Letter+lowercaseLetter, uppercaseLetter, titlecaseLetter, letterAnd, modifierLetter, otherLetter, letter :: CharSet+lowercaseLetter = cat LowercaseLetter+uppercaseLetter = cat UppercaseLetter+titlecaseLetter = cat TitlecaseLetter+letterAnd = lowercaseLetter + `union` uppercaseLetter + `union` titlecaseLetter+modifierLetter = cat ModifierLetter+otherLetter = cat OtherLetter+letter + = letterAnd + `union` modifierLetter + `union` otherLetter++-- Marks+nonSpacingMark, spacingCombiningMark, enclosingMark, mark :: CharSet+nonSpacingMark = cat NonSpacingMark+spacingCombiningMark = cat SpacingCombiningMark+enclosingMark = cat EnclosingMark+mark + = nonSpacingMark + `union` spacingCombiningMark + `union` enclosingMark++space, lineSeparator, paragraphSeparator, separator :: CharSet+space = cat Space+lineSeparator = cat LineSeparator+paragraphSeparator = cat ParagraphSeparator+separator + = space + `union` lineSeparator + `union` paragraphSeparator++mathSymbol, currencySymbol, modifierSymbol, otherSymbol, symbol :: CharSet+mathSymbol = cat MathSymbol+currencySymbol = cat CurrencySymbol+modifierSymbol = cat ModifierSymbol+otherSymbol = cat OtherSymbol+symbol + = mathSymbol + `union` currencySymbol + `union` modifierSymbol + `union` otherSymbol++decimalNumber, letterNumber, otherNumber, number :: CharSet+decimalNumber = cat DecimalNumber+letterNumber = cat LetterNumber+otherNumber = cat OtherNumber+number + = decimalNumber + `union` letterNumber + `union` otherNumber++dashPunctuation, openPunctuation, closePunctuation, initialQuote, + finalQuote, connectorPunctuation, otherPunctuation, punctuation :: CharSet++dashPunctuation = cat DashPunctuation+openPunctuation = cat OpenPunctuation+closePunctuation = cat ClosePunctuation+initialQuote = cat InitialQuote+finalQuote = cat FinalQuote+connectorPunctuation = cat ConnectorPunctuation+otherPunctuation = cat OtherPunctuation+punctuation + = dashPunctuation + `union` openPunctuation + `union` closePunctuation + `union` initialQuote + `union` finalQuote + `union` connectorPunctuation + `union` otherPunctuation++control, format, privateUse, surrogate, notAssigned, other :: CharSet+control = cat Control+format = cat Format+privateUse = cat PrivateUse+surrogate = cat Surrogate+notAssigned = cat NotAssigned+other = control + `union` format + `union` privateUse + `union` surrogate + `union` notAssigned
charset.cabal view
@@ -1,5 +1,5 @@ name: charset-version: 0.0+version: 0.1 license: BSD3 license-File: LICENSE copyright: (c) Edward Kmett 2010@@ -8,8 +8,8 @@ stability: Experimental category: Data homepage: http://github.com/ekmett/charset-synopsis: Fast unicode character sets-description: Fast unicode character sets+synopsis: Fast unicode character sets based on complemented PATRICIA tries+description: Fast unicode character sets based on complemented PATRICIA tries build-type: Simple build-depends: @@ -19,5 +19,8 @@ exposed-modules: Data.CharSet+ Data.CharSet.Common+ Data.CharSet.Posix.Ascii+ Data.CharSet.Unicode GHC-Options: -Wall -fspec-constr -fdicts-cheap -O2