The Haskell 98 Report
top | back | next | contents | function index
module Char ( isAscii, isLatin1, isControl, isPrint, isSpace, isUpper, isLower, isAlpha, isDigit, isOctDigit, isHexDigit, isAlphaNum, digitToInt, intToDigit, toUpper, toLower, ord, chr, readLitChar, showLitChar, lexLitChar, -- ...and what the Prelude exports Char, String ) where isAscii, isLatin1, isControl, isPrint, isSpace, isUpper, isLower, isAlpha, isDigit, isOctDigit, isHexDigit, isAlphaNum :: Char -> Bool toUpper, toLower :: Char -> Char digitToInt :: Char -> Int intToDigit :: Int -> Char ord :: Char -> Int chr :: Int -> Char lexLitChar :: ReadS String readLitChar :: ReadS Char showLitChar :: Char -> ShowS |
このライブラリは Unicode 文字集合上の限られた演算を供給している。 この文字集合の最初の 128 エントリは ASCII 文字集合と一致する。 次の 128 のエントリは Latin-1 文字集合ののこりの部分である。 このモジュールは全 Unicode 文字集合のうちの限られた部分を扱うに すぎない。すなわち、Unicode のフルセットの属性はこのライブラリでは 扱えない。
Unicode 文字はつぎの 5 つのおおまかなカテゴリーに分類される。 非表示文字、アルファベットの小文字、アルファベットのそれ以外、 数字、その他の表示可能文字。Haskell のプログラミングでの目的の ためには、すべての小文字でない文字は、大文字であるとして扱う。 ( Unicode では3つの可能性がある。大文字、小文字、タイトル文字) 数字は識別子の文字として使用可能であるが、ASCII 文字集合の 範囲にはないものについては数をあらわすものとしては使わない。
Unicode 文字の各種類について、True を返す述語を示しておく。
文字のタイプ | 述語 | |||
小文字のアルファベット | isPrint | isAlphaNum | isAlpha | isLower |
その他のアルファベット | isPrint | isAlphaNum | isAlpha | isUpper |
数字 | isPrint | isAlphaNum | ||
その他の表示可能文字 | isPrint | |||
非表示文字 |
isDigit、isOctDigit、および isHexDigit 関数は ASCII 文字のみ選択する。intToDigit および digitToInt は 1 文字の数字 Char とそれに対応する Int 間の変換をおこなう。digitToInt 演算は その引数が isHexDigit を満さなければ失敗する。しかし、 16 進数の大文字、小文字はともに認識できる(すなわち '0'..'9','a'..'f', 'A'..'F' が認識できる)。intToDigit はその引数が 0..15 の範囲になければ失敗する。 さらに 16 進数の場合は小文字を返す。
isSpace 関数は Latin-1 の範囲の空白のみを認識する。
関数 showLitChar は文字を Haskell でのプログラムソースの
エスケープ文字の規約をつかって表示可能文字列に変換する。関数
lexLitChar はその逆で、その文字をエンコードしている
文字のならびをを返す。readLitChar は同じことをするが、
それをエンコードしている文字に変換する。例えば、
showLitChar '\n' s = "\\n" ++ s
lexLitChar "\\nHello" = [("\\n", "Hello")]
readLitChar "\\nHello" = [('\n', "Hello")]
である。
関数 toUpper は英字小文字を対応する大文字へ変換する。 それ以外の文字はそのままである。対応する大文字があるすべての Unicode 文字は変換される。同様に toLower は対応する 小文字のある文字を変換し、それ以外をそのままにする。
ord 関数および chr 関数は fromEnum および toEnum の Char 限定版である。
module Char (
isAscii, isLatin1, isControl, isPrint, isSpace, isUpper, isLower,
isAlpha, isDigit, isOctDigit, isHexDigit, isAlphaNum,
digitToInt, intToDigit,
toUpper, toLower,
ord, chr,
readLitChar, showLitChar, lexLitChar,
-- ...and what the Prelude exports
Char, String
) where
import Array -- Used for character name table.
import Numeric (readDec, readOct, lexDigits, readHex)
import UnicodePrims -- Source of primitive Unicode functions.
-- Character-testing operations
isAscii, isLatin1, isControl, isPrint, isSpace, isUpper, isLower,
isAlpha, isDigit, isOctDigit, isHexDigit, isAlphaNum :: Char -> Bool
isAscii c = c < '\x80'
isLatin1 c = c <= '\xff'
isControl c = c < ' ' || c >= '\DEL' && c <= '\x9f'
isPrint = primUnicodeIsPrint
isSpace c = c `elem` " \t\n\r\f\v\xA0"
-- Only Latin-1 spaces recognized
isUpper = primUnicodeIsUpper -- 'A'..'Z'
isLower = primUnicodeIsLower -- 'a'..'z'
isAlpha c = isUpper c || isLower c
isDigit c = c >= '0' && c <= '9'
isOctDigit c = c >= '0' && c <= '7'
isHexDigit c = isDigit c || c >= 'A' && c <= 'F' ||
c >= 'a' && c <= 'f'
isAlphaNum = primUnicodeIsAlphaNum
-- Digit conversion operations
digitToInt :: Char -> Int
digitToInt c
| isDigit c = fromEnum c - fromEnum '0'
| c >= 'a' && c <= 'f' = fromEnum c - fromEnum 'a' + 10
| c >= 'A' && c <= 'F' = fromEnum c - fromEnum 'A' + 10
| otherwise = error "Char.digitToInt: not a digit"
intToDigit :: Int -> Char
intToDigit i
| i >= 0 && i <= 9 = toEnum (fromEnum '0' + i)
| i >= 10 && i <= 15 = toEnum (fromEnum 'a' + i - 10)
| otherwise = error "Char.intToDigit: not a digit"
-- Case-changing operations
toUpper :: Char -> Char
toUpper = primUnicodeToUpper
toLower :: Char -> Char
toLower = primUnicodeToLower
-- Character code functions
ord :: Char -> Int
ord = fromEnum
chr :: Int -> Char
chr = toEnum
-- Text functions
readLitChar :: ReadS Char
readLitChar ('\\':s) = readEsc s
readLitChar (c:s) = [(c,s)]
readEsc :: ReadS Char
readEsc ('a':s) = [('\a',s)]
readEsc ('b':s) = [('\b',s)]
readEsc ('f':s) = [('\f',s)]
readEsc ('n':s) = [('\n',s)]
readEsc ('r':s) = [('\r',s)]
readEsc ('t':s) = [('\t',s)]
readEsc ('v':s) = [('\v',s)]
readEsc ('\\':s) = [('\\',s)]
readEsc ('"':s) = [('"',s)]
readEsc ('\'':s) = [('\'',s)]
readEsc ('^':c:s) | c >= '@' && c <= '_'
= [(chr (ord c - ord '@'), s)]
readEsc s@(d:_) | isDigit d
= [(chr n, t) | (n,t) <- readDec s]
readEsc ('o':s) = [(chr n, t) | (n,t) <- readOct s]
readEsc ('x':s) = [(chr n, t) | (n,t) <- readHex s]
readEsc s@(c:_) | isUpper c
= let table = ('\DEL', "DEL") : assocs asciiTab
in case [(c,s') | (c, mne) <- table,
([],s') <- [match mne s]]
of (pr:_) -> [pr]
[] -> []
readEsc _ = []
match :: (Eq a) => [a] -> [a] -> ([a],[a])
match (x:xs) (y:ys) | x == y = match xs ys
match xs ys = (xs,ys)
showLitChar :: Char -> ShowS
showLitChar c | c > '\DEL' = showChar '\\' .
protectEsc isDigit (shows (ord c))
showLitChar '\DEL' = showString "\\DEL"
showLitChar '\\' = showString "\\\\"
showLitChar c | c >= ' ' = showChar c
showLitChar '\a' = showString "\\a"
showLitChar '\b' = showString "\\b"
showLitChar '\f' = showString "\\f"
showLitChar '\n' = showString "\\n"
showLitChar '\r' = showString "\\r"
showLitChar '\t' = showString "\\t"
showLitChar '\v' = showString "\\v"
showLitChar '\SO' = protectEsc (== 'H') (showString "\\SO")
showLitChar c = showString ('\\' : asciiTab!c)
protectEsc p f = f . cont
where cont s@(c:_) | p c = "\\&" ++ s
cont s = s
asciiTab = listArray ('\NUL', ' ')
["NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL",
"BS", "HT", "LF", "VT", "FF", "CR", "SO", "SI",
"DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB",
"CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US",
"SP"]
lexLitChar :: ReadS String
lexLitChar ('\\':s) = map (prefix '\\') (lexEsc s)
where
lexEsc (c:s) | c `elem` "abfnrtv\\\"'" = [([c],s)]
lexEsc ('^':c:s) | c >= '@' && c <= '_' = [(['^',c],s)]
-- Numeric escapes
lexEsc ('o':s) = [prefix 'o' (span isOctDigit s)]
lexEsc ('x':s) = [prefix 'x' (span isHexDigit s)]
lexEsc s@(d:_) | isDigit d = [span isDigit s]
-- Very crude approximation to \XYZ.
lexEsc s@(c:_) | isUpper c = [span isCharName s]
lexEsc _ = []
isCharName c = isUpper c || isDigit c
prefix c (t,s) = (c:t, s)
lexLitChar (c:s) = [([c],s)]
lexLitChar "" = []
The Haskell 98 Report
top | back | next | contents | function index
December 2002