or1ko's diary

日々を書きます

Windows版HaskellでUTF8のファイル読み書き

Haskell Platform 7.10.2-aをインストールした際に、日本語(utf8)の扱いがわからなくなってしまって、ずっとほっといたのだが、ふと思い出して調べてみた。


紆余曲折したが、ポイントとしては下記の2点。

  • Handleにutf8を指定

ファイルの読み書きなどのデフォルトのエンコーディングがcp932になっているため、utf8のファイルを読み込む場合は、Handleのエンコーディングをutf8に変更する

  • ByteStringを扱う場合は、utf8-stringモジュールを使う

ただし、Stringで読みこんだ文字列をByteStringに変換して使う。標準でインストールされるByteStringモジュールに存在するreadFileなどの関数がないため。

サンプルとして、第一引数で指定したファイルをutf8の文字コードで読み込み、内容を標準出力するプログラムを記載する。

import System.Environment
import System.IO

main = do
          filename <- head <$> getArgs 
          withFile filename ReadMode f 
          where
            f h = hSetEncoding h utf8 >> hGetContents h >>= putStrLn

また、Powershellから標準出力をrunghcに渡す場合、下記のコマンドを実行する。

$OutputEncoding = [Text.Encoding]::Default

コマンドに渡す際のエンコーディングがasciiになっているため、cp932に変更する。

毎回ハンドルのエンコーディングを変更するのは面倒だという場合は、
GHC.IO.EncodingのsetLocaleEncoding関数で、デフォルト値を変更することができる。ただし、標準出力などのエンコーディングも変更されるので、注意する。