2009年1月24日土曜日

Haskell の print関数 (utf8-string) で日本語を出力

1. print 関数で日本語が文字化け

Haskell で print 関数により日本語を出力すると、文字化けする。 (+_+)

例えば、「人」を表わす代数的データ型 Person が、「名前」と「年齢」を持っているとする。Person 型を Show クラスの導出インスタンスとして、Person 型の値を print 関数によって出力させる。ファイルは UTF8 で保存。

(cf. Haskell で日本語表示 - utf8-string を利用して)

import qualified System.IO.UTF8 as U

data Person = Person {name :: String,
                      age  :: Int} deriving Show

main = U.print $ Person "太郎" 20

結果は、

Person {name = "\22826\37070", age = 20}

なぜか名前が変な数字に。 (@_@;)

 

2. System.IO.UTF8 の print 関数は、ユニコード値を出力する

System.IO.UTF8 の説明には、

… This function differs from the System.IO.print in that it preserves any UTF8 encoding of the shown value.

UTF8 の値を保持しているとは、どういうことだろう…?

 

JavaScript で Unicode の値を確認

Javascriptで数値文字参照の値を求める方法」のサイトで、「太郎」と入力したら、結果は、

太郎

Haskell で出力したときと、同じ数字が返ってきた。

そこで、上記サイトの JavaScript のソースを見たら、charCodeAt メソッド利用により、値が出力されている。

String – MDCcharCodeAt によると、

与えられた インデックスの文字の Unicode の値を示す数を返します。

なるほど、あの数字は Unicode を表わす値だったということか。

念のため、JavaScript で、以下のコードを実行。

var tarou = "太郎"
for (var i=0; i < tarou.length; i++){
    console.log(tarou.charCodeAt(i));
}

結果は、先ほど同じになった。

22826

37070

 

3. Show クラスの導出インスタンスを利用せず、自前で実装

上記のように、Unicode 値ではなくて、print 関数で文字を出力したい。

に書かれているコードでは、printf 関数が使われており、日本語が出力できている。この関数によって日本語が表示されるのか、それとも、導出インスタンスを利用していないから出力されるのだろうか?

試しに Person 型を Show クラスのインスタンスにして、show 関数を実装してみると、

instance Show Person where
    show (Person name age) = name ++ " " ++ show age

結果、日本語が表示された。

太郎 20

ということは、deriving Show が原因だったのかな?

 

4. その他


5. 関連記事