以下のようなファイルがあったとします。
prefectures.txt
大阪府
和歌山県
高知県
愛媛県
これを sort コマンドで並び替えると以下のようになります。
$ sort prefectures.txt
大阪府
愛媛県
高知県
和歌山県
Haskell で並び替えるなら以下のようなプログラムになります。
Main.hs
import Data.List (sort)
import System.Environment (getArgs)
main :: IO ()
main = do
args <- getArgs
contents <- readFile $ args !! 0
mapM_ putStrLn $ sort $ lines contents
実行すると以下のようになります。
$ stack exec -- sort prefectures.txt
和歌山県
大阪府
愛媛県
高知県
あれ、sort コマンドと結果が違いますね。
結果が異なる理由
わかりません (><;/~
ご存じの方はコメントでご教示ください。
調べてみた
簡単のため「和歌山県」と「愛媛県」で比較してみます。
テキストは UTF-8 で保存されていて、それぞれ以下のようなバイト列です。
- 和歌山県:
e5 92 8c e6 ad 8c e5 b1 b1 e7 9c 8c 0a
- 愛知県:
e6 84 9b e5 aa 9b e7 9c 8c 0a
「和歌山県」の方が若いですが、sort コマンドの結果は一番下です。
Haskell の Char は UCS-4 なので Haskell の String は以下のようなバイト列になるはずです。
- 和歌山県:
00 00 54 8c 00 00 6b 4c 00 00 5c 71 00 00 77 0c 00 00 00 0a
- 愛知県:
00 00 61 1b 00 00 5a 9b 00 00 77 0c 00 00 00 0a
こちらも「和歌山県」の方が若く、こちらは sort 関数の結果と一致します。
sort コマンドの内部コード?に起因するのでしょうか? sort コマンドはバイナリを与えても正常に動作しないので、単にバイト列でソートしているのではなく、何らかの文字コード変換が行われているような気がします。