コードへの埋め込み
str = " システム "
どう扱っているのか、確かめてみます。
import Data.Char map ord str → [32,12471,12473,12486,12512,32]
Char は1バイトではなく、UTF-8 の文字が収容できる大きさになっているようです。うまくできていますね。
UTF-8 ファイルの読み込み
UTF-8 で " システム " と書いたファイルを用意し、以下のコードを実行して、読み込ませます。
main = do cs <- getContents print $ map ord cs
結果は、こうなりました。
→ [32,227,130,183,227,130,185,227,131,134,227,131,160,32]
単なるバイトストーリムとして扱っているのが分ります。
ここで、以下のような先頭と末尾の空白を削るコードを考えます。
import Data.Char strip = reverse. dropWhile isSpace . reverse . dropWhile isSpace main = do cs <- getContents print $ map ord $ strip cs
このコードは、以下のように問題を起こします。
→ [227,130,183,227,130,185,227,131,134,227,131]
「ム」の3バイト目である 160 が削られています。原因は、isSpace が Non-breaking space (160) に対し、True を返すからです。
これを解決するためには、utf8-string というパッケージを入れるとよいようです。
import Data.Char import qualified System.IO.UTF8 as U8 strip = reverse. dropWhile isSpace . reverse . dropWhile isSpace main = do cs <- U8.getContents print $ map ord $ strip cs
実行すると、こうなります。
→ [12471,12473,12486,12512]
まとめ
Char が UTF-8 を収容できるように作られているのは、素敵ですね。