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).
26 , isAscii, isLatin1, isControl, isSpace
27 , isLower, isUpper, isAlpha, isAlphaNum, isPrint
28 , isDigit, isOctDigit, isHexDigit
29 , isAsciiUpper, isAsciiLower
31 , isLetter, isMark, isNumber, isPunctuation, isSymbol, isSeparator
33 , GeneralCategory(..), generalCategory
37 , toUpper, toLower, toTitle -- :: Char -> Char
39 -- * Single digit characters
40 , digitToInt -- :: Char -> Int
41 , intToDigit -- :: Int -> Char
43 -- * Numeric representations
44 , ord -- :: Char -> Int
45 , chr -- :: Int -> Char
47 -- * String representations
48 , showLitChar -- :: Char -> ShowS
49 , lexLitChar -- :: ReadS String
50 , readLitChar -- :: ReadS Char
52 -- Implementation checked wrt. Haskell 98 lib report, 1/99.
55 #ifdef __GLASGOW_HASKELL__
57 import GHC.Real (fromIntegral)
59 import GHC.Read (Read, readLitChar, lexLitChar)
71 import Prelude(Char,String)
74 foreign import ccall unsafe "WCsubst.h u_gencat" wgencat :: CInt -> Int
77 -- | Convert a single digit 'Char' to the corresponding 'Int'.
78 -- This function fails unless its argument satisfies 'isHexDigit',
79 -- but recognises both upper and lower-case hexadecimal digits
80 -- (i.e. @\'0\'@..@\'9\'@, @\'a\'@..@\'f\'@, @\'A\'@..@\'F\'@).
81 digitToInt :: Char -> Int
83 | isDigit c = ord c - ord '0'
84 | c >= 'a' && c <= 'f' = ord c - ord 'a' + 10
85 | c >= 'A' && c <= 'F' = ord c - ord 'A' + 10
86 | otherwise = error ("Char.digitToInt: not a digit " ++ show c) -- sigh
88 #ifndef __GLASGOW_HASKELL__
89 isAsciiUpper, isAsciiLower :: Char -> Bool
90 isAsciiLower c = c >= 'a' && c <= 'z'
91 isAsciiUpper c = c >= 'A' && c <= 'Z'
94 -- | Unicode General Categories (column 2 of the UnicodeData table)
95 -- in the order they are listed in the Unicode standard.
98 = UppercaseLetter -- ^ Lu: Letter, Uppercase
99 | LowercaseLetter -- ^ Ll: Letter, Lowercase
100 | TitlecaseLetter -- ^ Lt: Letter, Titlecase
101 | ModifierLetter -- ^ Lm: Letter, Modifier
102 | OtherLetter -- ^ Lo: Letter, Other
103 | NonSpacingMark -- ^ Mn: Mark, Non-Spacing
104 | SpacingCombiningMark -- ^ Mc: Mark, Spacing Combining
105 | EnclosingMark -- ^ Me: Mark, Enclosing
106 | DecimalNumber -- ^ Nd: Number, Decimal
107 | LetterNumber -- ^ Nl: Number, Letter
108 | OtherNumber -- ^ No: Number, Other
109 | ConnectorPunctuation -- ^ Pc: Punctuation, Connector
110 | DashPunctuation -- ^ Pd: Punctuation, Dash
111 | OpenPunctuation -- ^ Ps: Punctuation, Open
112 | ClosePunctuation -- ^ Pe: Punctuation, Close
113 | InitialQuote -- ^ Pi: Punctuation, Initial quote
114 | FinalQuote -- ^ Pf: Punctuation, Final quote
115 | OtherPunctuation -- ^ Po: Punctuation, Other
116 | MathSymbol -- ^ Sm: Symbol, Math
117 | CurrencySymbol -- ^ Sc: Symbol, Currency
118 | ModifierSymbol -- ^ Sk: Symbol, Modifier
119 | OtherSymbol -- ^ So: Symbol, Other
120 | Space -- ^ Zs: Separator, Space
121 | LineSeparator -- ^ Zl: Separator, Line
122 | ParagraphSeparator -- ^ Zp: Separator, Paragraph
123 | Control -- ^ Cc: Other, Control
124 | Format -- ^ Cf: Other, Format
125 | Surrogate -- ^ Cs: Other, Surrogate
126 | PrivateUse -- ^ Co: Other, Private Use
127 | NotAssigned -- ^ Cn: Other, Not Assigned
128 deriving (Eq, Ord, Enum, Read, Show, Bounded)
130 -- | Retrieves the general Unicode category of the character.
131 generalCategory :: Char -> GeneralCategory
132 #if defined(__GLASGOW_HASKELL__) || defined(__NHC__)
133 generalCategory c = toEnum (wgencat (fromIntegral (ord c)))
136 generalCategory c = toEnum (primUniGenCat c)
139 -- derived character classifiers
141 isLetter :: Char -> Bool
142 isLetter c = case generalCategory c of
143 UppercaseLetter -> True
144 LowercaseLetter -> True
145 TitlecaseLetter -> True
146 ModifierLetter -> True
150 isMark :: Char -> Bool
151 isMark c = case generalCategory c of
152 NonSpacingMark -> True
153 SpacingCombiningMark -> True
154 EnclosingMark -> True
157 isNumber :: Char -> Bool
158 isNumber c = case generalCategory c of
159 DecimalNumber -> True
164 isPunctuation :: Char -> Bool
165 isPunctuation c = case generalCategory c of
166 ConnectorPunctuation -> True
167 DashPunctuation -> True
168 OpenPunctuation -> True
169 ClosePunctuation -> True
172 OtherPunctuation -> True
175 isSymbol :: Char -> Bool
176 isSymbol c = case generalCategory c of
178 CurrencySymbol -> True
179 ModifierSymbol -> True
183 isSeparator :: Char -> Bool
184 isSeparator c = case generalCategory c of
186 LineSeparator -> True
187 ParagraphSeparator -> True
191 -- dummy implementation
192 toTitle :: Char -> Char