1 {-# OPTIONS_GHC -fno-implicit-prelude #-}
2 -----------------------------------------------------------------------------
5 -- Copyright : (c) The University of Glasgow 2001
6 -- License : BSD-style (see the file libraries/base/LICENSE)
8 -- Maintainer : libraries@haskell.org
10 -- Portability : portable
12 -- The Char type and associated operations.
14 -----------------------------------------------------------------------------
22 -- * Character classification
23 -- | Unicode characters are divided into letters, numbers, marks,
24 -- punctuation, symbols, separators (including spaces) and others
25 -- (including control characters).
27 , isLower, isUpper, isAlpha, isAlphaNum, isPrint
28 , isDigit, isOctDigit, isHexDigit
29 , isLetter, isMark, isNumber, isPunctuation, isSymbol, isSeparator
33 , isAsciiUpper, isAsciiLower
35 -- ** Unicode general categories
36 , GeneralCategory(..), generalCategory
39 , toUpper, toLower, toTitle -- :: Char -> Char
41 -- * Single digit characters
42 , digitToInt -- :: Char -> Int
43 , intToDigit -- :: Int -> Char
45 -- * Numeric representations
46 , ord -- :: Char -> Int
47 , chr -- :: Int -> Char
49 -- * String representations
50 , showLitChar -- :: Char -> ShowS
51 , lexLitChar -- :: ReadS String
52 , readLitChar -- :: ReadS Char
54 -- Implementation checked wrt. Haskell 98 lib report, 1/99.
57 #ifdef __GLASGOW_HASKELL__
60 import GHC.Real (fromIntegral)
62 import GHC.Read (Read, readLitChar, lexLitChar)
69 import Hugs.Prelude (Ix)
75 import Prelude(Char,String)
79 foreign import ccall unsafe "WCsubst.h u_gencat" wgencat :: CInt -> CInt
82 -- | Convert a single digit 'Char' to the corresponding 'Int'.
83 -- This function fails unless its argument satisfies 'isHexDigit',
84 -- but recognises both upper and lower-case hexadecimal digits
85 -- (i.e. @\'0\'@..@\'9\'@, @\'a\'@..@\'f\'@, @\'A\'@..@\'F\'@).
86 digitToInt :: Char -> Int
88 | isDigit c = ord c - ord '0'
89 | c >= 'a' && c <= 'f' = ord c - ord 'a' + 10
90 | c >= 'A' && c <= 'F' = ord c - ord 'A' + 10
91 | otherwise = error ("Char.digitToInt: not a digit " ++ show c) -- sigh
93 #ifndef __GLASGOW_HASKELL__
94 isAsciiUpper, isAsciiLower :: Char -> Bool
95 isAsciiLower c = c >= 'a' && c <= 'z'
96 isAsciiUpper c = c >= 'A' && c <= 'Z'
99 -- | Unicode General Categories (column 2 of the UnicodeData table)
100 -- in the order they are listed in the Unicode standard.
103 = UppercaseLetter -- ^ Lu: Letter, Uppercase
104 | LowercaseLetter -- ^ Ll: Letter, Lowercase
105 | TitlecaseLetter -- ^ Lt: Letter, Titlecase
106 | ModifierLetter -- ^ Lm: Letter, Modifier
107 | OtherLetter -- ^ Lo: Letter, Other
108 | NonSpacingMark -- ^ Mn: Mark, Non-Spacing
109 | SpacingCombiningMark -- ^ Mc: Mark, Spacing Combining
110 | EnclosingMark -- ^ Me: Mark, Enclosing
111 | DecimalNumber -- ^ Nd: Number, Decimal
112 | LetterNumber -- ^ Nl: Number, Letter
113 | OtherNumber -- ^ No: Number, Other
114 | ConnectorPunctuation -- ^ Pc: Punctuation, Connector
115 | DashPunctuation -- ^ Pd: Punctuation, Dash
116 | OpenPunctuation -- ^ Ps: Punctuation, Open
117 | ClosePunctuation -- ^ Pe: Punctuation, Close
118 | InitialQuote -- ^ Pi: Punctuation, Initial quote
119 | FinalQuote -- ^ Pf: Punctuation, Final quote
120 | OtherPunctuation -- ^ Po: Punctuation, Other
121 | MathSymbol -- ^ Sm: Symbol, Math
122 | CurrencySymbol -- ^ Sc: Symbol, Currency
123 | ModifierSymbol -- ^ Sk: Symbol, Modifier
124 | OtherSymbol -- ^ So: Symbol, Other
125 | Space -- ^ Zs: Separator, Space
126 | LineSeparator -- ^ Zl: Separator, Line
127 | ParagraphSeparator -- ^ Zp: Separator, Paragraph
128 | Control -- ^ Cc: Other, Control
129 | Format -- ^ Cf: Other, Format
130 | Surrogate -- ^ Cs: Other, Surrogate
131 | PrivateUse -- ^ Co: Other, Private Use
132 | NotAssigned -- ^ Cn: Other, Not Assigned
133 deriving (Eq, Ord, Enum, Read, Show, Bounded, Ix)
135 -- | The Unicode general category of the character.
136 generalCategory :: Char -> GeneralCategory
137 #if defined(__GLASGOW_HASKELL__) || defined(__NHC__)
138 generalCategory c = toEnum $ fromIntegral $ wgencat $ fromIntegral $ ord c
141 generalCategory c = toEnum (primUniGenCat c)
144 -- derived character classifiers
146 -- | Selects alphabetic Unicode characters (lower-case, upper-case and
147 -- title-case letters, plus letters of caseless scripts and modifiers letters).
148 -- This function is equivalent to 'Data.Char.isAlpha'.
149 isLetter :: Char -> Bool
150 isLetter c = case generalCategory c of
151 UppercaseLetter -> True
152 LowercaseLetter -> True
153 TitlecaseLetter -> True
154 ModifierLetter -> True
158 -- | Selects Unicode mark characters, e.g. accents and the like, which
159 -- combine with preceding letters.
160 isMark :: Char -> Bool
161 isMark c = case generalCategory c of
162 NonSpacingMark -> True
163 SpacingCombiningMark -> True
164 EnclosingMark -> True
167 -- | Selects Unicode numeric characters, including digits from various
168 -- scripts, Roman numerals, etc.
169 isNumber :: Char -> Bool
170 isNumber c = case generalCategory c of
171 DecimalNumber -> True
176 -- | Selects Unicode punctuation characters, including various kinds
177 -- of connectors, brackets and quotes.
178 isPunctuation :: Char -> Bool
179 isPunctuation c = case generalCategory c of
180 ConnectorPunctuation -> True
181 DashPunctuation -> True
182 OpenPunctuation -> True
183 ClosePunctuation -> True
186 OtherPunctuation -> True
189 -- | Selects Unicode symbol characters, including mathematical and
191 isSymbol :: Char -> Bool
192 isSymbol c = case generalCategory c of
194 CurrencySymbol -> True
195 ModifierSymbol -> True
199 -- | Selects Unicode space and separator characters.
200 isSeparator :: Char -> Bool
201 isSeparator c = case generalCategory c of
203 LineSeparator -> True
204 ParagraphSeparator -> True
208 -- dummy implementation
209 toTitle :: Char -> Char