Data.ByteString
Kiểu String trong Haskell được định nghĩa đơn giản là [Char], tức là một danh sách các ký tự. Cách biểu diễn này tuy trực quan nhưng lại mang theo nhược điểm về hiệu suất do tính chất lazy evaluation của List. Khi làm việc với các tệp tin nhị phân có kích thước lớn, ByteString sẽ là lựa chọn tối ưu hơn so với String.
ByteString được chia thành hai loại chính:
- Phiên bản Lazy nằm trong module Data.ByteString.Lazy, ký hiệu là Data.ByteString.Lazy.ByteString. Bên trong, module này tổ chức dữ liệu thành các chunk có kích thước 64KB.
- Phiên bản Strict nằm trong module Data.ByteString, ký hiệu là Data.ByteString.ByteString.
Prelude> import qualified Data.ByteString.Lazy as BL
Prelude BL> import qualified Data.ByteString as BS
Prelude BL BS> BL.pack [104,101,108,108,111]
"hello"
Prelude BL BS> BL.fromChunks [BS.pack [50,51,52], BS.pack [53,54,55], BS.pack [56,57,58]]
"23456789:;"
Prelude BL BS> BL.cons 88 $ BL.pack [65,66,67,68]
"XABCD"
Prelude BL BS> foldr BL.cons' BL.empty [70..80]
"FGHIJKLMNOP"
Data.Text
Đối với các tệp tin văn bản có dung lượng lớn, Text cung cấp giải pháp tối ưu hơn so với String. Text được thiết kế với mục tiêu thân thiện với Unicode, hỗ trợ đầy đủ các ký tự đa byte.
Text cũng có hai phiên bản:
- Lazy module Data.Text.Lazy cung cấp kiểu Data.Text.Lazy.Text, sử dụng cơ chế chunks bên trong.
- Strict module Data.Text cung cấp kiểu Data.Text.Text.
Prelude> import qualified Data.Text.Lazy as TL
Prelude TL> :t TL.pack "hello"
TL.pack "hello" :: TL.Text
Prelude TL> TL.replace (TL.pack "x") (TL.pack "y") (TL.pack "xAxAxA")
"yAyAyA"
Prelude TL> TL.splitOn (TL.pack "x") (TL.pack "xBxBxB")
["","B","B","B"]
- Hàm pack :: String -> Text chuyển đổi String thành Text.
Data.Text.Encoding
Module Encoding cung cấp các hàm để chuyển đổi giữa ByteString và Text. Text có hai module liên quan là Data.Text.Encoding.Lazy (phiên bản lazy) và Data.Text.Encoding (phiên bản strict).
Module Lazy hỗ trợ chuyển đổi giữa Data.ByteString.Lazy.ByteString và Data.Text.Lazy.Text. Trong khi đó, module Strict phục vụ việc chuyển đổi giữa Data.ByteString.ByteString và Data.Text.Text.
Data.String.Conversions
$ cabal install string-conversions
Installed string-conversions-0.4.0.1
Prelude> :m +Data.String.Conversions
Prelude Data.String.Conversions>
Module Conversions cho phép chuyển đổi giữa năm loại chuỗi:
- String
- Data.ByteString.ByteString - viết tắt là StrictByteString (SBS)
- Data.ByteString.Lazy.ByteString - viết tắt là LazyByteString (LBS)
- Data.Text.Text - viết tắt là StrictText (ST)
- Data.Text.Lazy.Text - viết tắt là LazyText (LT)
Prelude Data.String.Conversions> cs "test" :: ST
"test"
- ConvertibleStrings là một typeclass, cả năm loại chuỗi đều là instance của nó.
- Hàm cs :: ConvertibleStrings a b => a -> b tự động thực hiện chuyển đổi dựa trên kiểu đầu vào và đầu ra.
OverloadedStrings
GHC hỗ trợ language extension tên là OverloadedStrings.
- Khi không sử dụng extension này, mọi chuỗi ký tự đều thuộc kiểu String (tức là [Char]).
- Khi bật extension này, các chuỗi ký tự sẽ thuộc kiểu IsString a => a.
- String, ByteString, Text đều là instance của class IsString.
module Data.String where
class IsString a where
fromString :: String -> a
{-# LANGUAGE OverloadedStrings #-}
import qualified Data.Text.IO as TIO
messageA :: Text
messageA = " Xin chao "
messageB :: BS.ByteString
messageB = " Xin chao "
messageC :: String
messageC = " Xin chao "
main = do
putStrLn "Xin chao tu String!"
TIO.putStrLn "Xin chao tu Text!"
Text là Monoid
Prelude Data.Text> ("chao" :: Text) <> (" ban" :: Text)
"chao ban"