iconvを外部プロセスとして呼び出して漢字コードを変換する

何もないよりはマシかなーと思って以下の関数を書いてみました。HaskellWindowsで使うとそのままではテキストモードになっているので、iconvとのやりとりのハンドルも強制的にテキストモードに設定しています。テキストモードにしないと改行文字がおかしくなります。iconvによってはいらないものもあるんですが、あまり詳しくは調べてません(Cygwinに付属のiconvはテキストモードに設定しなくてもOKでした(Cygwinのbinmodeが効いているのかな?)。RubyのOneClickInstallerに付属のiconvはテキストモードにする必要がありました)。

iconv :: String -> String -> String -> IO String
iconv from to s = do
  (input, output, _, _) <- runInteractiveProcess
                             "iconv" ["-f", from, "-t", to]
                             Nothing Nothing
  -- set text mode for windows.
  hSetBinaryMode input  False
  hSetBinaryMode output False
  hPutStr input s
  hClose input
  hGetContents output

完全なプログラムは以下のようになります。ここでは標準入力をEUCからShiftJISに変換して標準出力に出力しています。
ファイル: iconv.hs

module Main (main) where

import System.IO
import System.Process (runInteractiveProcess)

iconv :: String -> String -> String -> IO String
iconv from to s = do
  (input, output, _, _) <- runInteractiveProcess
                             "iconv" ["-f", from, "-t", to]
                             Nothing Nothing
  -- set text mode for windows.
  hSetBinaryMode input  False
  hSetBinaryMode output False
  hPutStr input s
  hClose input
  hGetContents output

main :: IO ()  
main = putStr =<< iconv "EUC-JP" "SHIFT_JIS" =<< getContents

ファイル: Makefile

TARGET  = iconv
SOURCES = iconv.hs

HC      = ghc
HCFLAGS = -W -fno-warn-unused-matches --make

all: $(TARGET)

$(TARGET): $(SOURCES)
	$(HC) $(HCFLAGS) $< -o $@

clean:
	rm -f $(TARGET) *.o *.hi *.exe