Data.Char
Module Data.Char
thực hiện những nhiệm vụ mà tên gọi của nó gợi ra. Nó xuất khẩu những hàm thao tác với kí tự. Module này cũng có ích đối với việc lọc và ánh xạ trên các chuỗi vì chuỗi chỉ là danh sách các kí tự.
Data.Char
xuất khẩu một loạt những vị từ thao tác với kí tự; nghĩa là những hàm nhận vào một kí tự rồi cho ta biết rằng liệu một giả thiết nào về kí tự này là đúng hay sai. Sau đây là các vị từ:
isControl
kiểm tra xem một kí tự có phải là kí tự điều khiển hay không.
isSpace
kiểm tra xem một kí tự có phải là kí tự trắng hay không; các kí tự trắng gồm có dấu cách, tab, xuống dòng, v.v.
isLower
kiểm tra xem một kí tự có phải là chữ thường không.
isUpper
kiểm tra xem một kí tự có phải là chữ in không.
isAlpha
kiểm tra xem một kí tự có phải là chữ cái không.
isAlphaNum
kiểm tra xem một kí tự có phải là chữ cái hoặc chữ số không.
isPrint
kiểm tra xem một kí tự có in được hay không. Những kí tự như kí tự điều khiển chẳng hạn, thì không in được.
isDigit
kiểm tra xem một kí tự có phải là chữ số không.
isOctDigit
kiểm tra xem một kí tự có phải là chữ số trong hệ bát phân không.
isHexDigit
kiểm tra xem một kí tự có phải là chữ số trong hệ thập lục phân không.
isLetter
kiểm tra xem một kí tự có phải là chữ cái không. [Hai hàm isLetter
và isAlpha
tương đương với nhau.]
isMark
kiểm tra kí tự dấu Unicode; những kí tự dấu này kết hợp với kí tự liền trước nó để tạo thành các chữ có dấu. Nếu bạn nói tiếng Pháp, hãy dùng hàm này.
isNumber
kiểm tra xem một kí tự có phải là chữ số không.
isPunctuation
kiểm tra xem một kí tự có phải là dấu câu không.
isSymbol
kiểm tra xem một kí tự có phải là dấu kí hiệu toán hoặc kí hiệu tiền tệ không.
isSeparator
kiểm tra các dấu trống và dấu ngăn cách Unicode.
isAscii
kiểm tra xem một kí tự có rơi vào nhóm 128 kí tự đầu tiên trong bảng mã Unicode không.
isLatin1
kiểm tra xem một kí tự có rơi vào nhóm 256 kí tự đầu tiên trong bảng mã Unicode không.
isAsciiUpper
kiểm tra xem một kí tự có phải là ASCII và viết in không.
isAsciiLower
kiểm tra xem một kí tự có phải là ASCII và viết thường không.
Tất cả những vị từ này đều có dấu ấn kiểu là Char -> Bool
. Trong đa số các trường hợp bạn sẽ dùng đặc điểm này để lọc ra chuỗi hoặc những thứ như vậy. Chẳng hạn, giả sử ta viết một chương trình nhận vào tên người dùng mà tên gọi này chỉ chứa những chữ cái. Ta có thể dùng hàm all
trong Data.List
kết hợp với vị từ Data.Char
để quyết định xem tên được nhập vào đó có hợp lệ không.
ghci> all isAlphaNum "bobby283" True ghci> all isAlphaNum "eddy the fish!" False
Hay! Trong trường hợp bạn không nhớ, all
nhận vào một vị từ cùng một danh sách rồi trả lại True
chỉ khi vị từ đó thỏa mãn tất cả các phần tử trong danh sách.
Ta cũng có thể dùng isSpace
để mô phỏng hàm words
trong Data.List
.
ghci> words "hey guys its me" ["hey","guys","its","me"] ghci> groupBy ((==) `on` isSpace) "hey guys its me" ["hey"," ","guys"," ","its"," ","me"] ghci>
Hừm, được rồi, nó hoạt động kiểu như words
song bỏ lại cho ta những phần tử chỉ chứa những dấu cách. Hừm, ta sẽ làm gì đây? Tôi biết rồi, hãy lọc đi những thứ rác đó.
ghci> filter (not . any isSpace) . groupBy ((==) `on` isSpace) $ "hey guys its me" ["hey","guys","its","me"]
A ha!
Lớp Data.Char
cũng xuất khẩu một kiểu dữ liệu giống như Ordering
. Kiểu Ordering
có thể nhận giá trị LT
, EQ
hoặc GT
. Đó là một dạng liệt kê. Nó mô tả một vài kết quả có thể xảy ra khi so sánh hai phần tử. Kiểu GeneralCategory
cũng là một dạng liệt kê. Nó trình bày một số thể loại mà một kí tự có thể rơi vào. Hàm cơ bản để lấy thể loại tổng quát của một kí tự là generalCategory
. Nó có kiểu generalCategory :: Char -> GeneralCategory
. Có khoảng 31 thể loại, vì vậy chúng tôi sẽ không kể hết ra ở đây, nhưng ta hãy thử dùng hàm này xem.
ghci> generalCategory ' ' Space ghci> generalCategory 'A' UppercaseLetter ghci> generalCategory 'a' LowercaseLetter ghci> generalCategory '.' OtherPunctuation ghci> generalCategory '9' DecimalNumber ghci> map generalCategory " \t\nA9?|" [Space,Control,Control,UppercaseLetter,DecimalNumber,OtherPunctuation,MathSymbol]
Vì kiểu GeneralCategory
là một phần của lớp Eq
, ta cũng có thể kiểm tra những thứ như generalCategory c == Space
.
toUpper
chuyển một kí tự thành chữ viết in. Các dấu cách, chữ số, v.v. giữ nguyên không đổi.
toLower
chuyển một kí tự thành chữ viết thường.
toTitle
chuyển một kí tự thành chữ tiêu đề. Tuyệt đại đa số kí tự thfi chữ tiêu đề cũng như chữu viết in.
digitToInt
chuyển một kí tự thành kiểu Int
. Muốn chuyển đổi được, kí tự phải nằm trong khoảng '0'..'9'
, 'a'..'f'
hoặc 'A'..'F'
.
ghci> map digitToInt "34538" [3,4,5,3,8] ghci> map digitToInt "FF85AB" [15,15,8,5,10,11]
intToDigit
là hàm ngược của digitToInt
. Nó nhận vào một Int
trong khoảng từ 0..15
rồi chuyển sang một chữ cái viết thường.
ghci> intToDigit 15 'f' ghci> intToDigit 5 '5'
Các hàm ord
và chr
chuyển đổi kí tự thành số tương ứng và ngược lại:
ghci> ord 'a' 97 ghci> chr 97 'a' ghci> map ord "abcdefgh" [97,98,99,100,101,102,103,104]
Hiệu số giữa hai giá trị ord
của hai kí tự sẽ bằng khoảng cách giữa hai kí tự đó trong bảng mã Unicode.
Mật mã Caesar là một phương pháp thô sơ để mã hóa thông điệp chứa nhiều kí tự bằng cách chuyển từng kí tự đi một số vị trí nhất định trong bảng chữ cái. Ta có thể dễ dàng tạo ra một dạng mật mã Caesar, chỉ khác là không bị giới hạn ở những kí tự trong bảng chữ cái.
encode :: Int -> String -> String encode shift msg = let ords = map ord msg shifted = map (+ shift) ords in map chr shifted
Ở đây, đầu tiên là ta chuyển chuỗi thành một danh sách các số. Sau đó ta đem cộng khoảng dịch chuyển vào từng số trước khi chuyển ngược danh sách số về những kí tự. Nếu là người chuyên dùng hàm hợp thì bạn có thể viết phần thân của hàm này như sau:map (chr . (+ shift) . ord) msg
. Ta hãy thử mã hóa một vài thông điệp.
ghci> encode 3 "Heeeeey" "Khhhhh|" ghci> encode 4 "Heeeeey" "Liiiii}" ghci> encode 1 "abcd" "bcde" ghci> encode 5 "Marry Christmas! Ho ho ho!" "Rfww~%Hmwnxyrfx&%Mt%mt%mt&"
Việc mã hóa như vậy là ổn. Việc giải mã về cơ bản là dịch chuyển ngược về một số vị trí như ban đầu đã dịch chuyển đi.
decode :: Int -> String -> String decode shift msg = encode (negate shift) msg
ghci> encode 3 "Im a little teapot" "Lp#d#olwwoh#whdsrw" ghci> decode 3 "Lp#d#olwwoh#whdsrw" "Im a little teapot" ghci> decode 5 . encode 5 $ "This is a sentence" "This is a sentence"
ConversionConversion EmoticonEmoticon