この記事は、Haskell Advent Calendar 2019 22日目の記事です。

例年どおりタイプセーフプリキュア！の話をするつもりでしたが、ネタが実装できなかったのでunicode-showの話をします 。

まぁ、こちらの方がみなさんにとっては有益でしょうし🙃

Link to

here Haskell を始めるとあるある

GHCiに日本語を入力したり…

日本語を print したり…

日本語を show したり…

すると、日本語の大半が変な文字列に変わってしまいました😥。

へ… 変な文字列じゃないし！エスケープシーケンスに変換しただけだから！

これは、Haskell標準における show 関数の残念な仕様です。

show 関数に文字列を渡すと、ダブルクォートで囲った上で、ASCII範囲外の文字列や、ASCIIの非表示文字などをエスケープシーケンスに変換して返します。

これは、 show 関数をデバッグで使用した際、指定した文字列にどんな文字が含まれているか、簡単にわかるようにするための仕様です。

文字の文字コードを表示すれば、NULL文字や制御文字、ゼロ幅文字、特殊なスペースなど、視認しにくいおかしな文字が含まれていても、一目でわかるのです。

しかしこれは日本語話者である我々にとって、少なくとも日本語の文字に関しては「余計なお世話」です。

NULL文字やASCIIの制御文字といった本来画面に表示することがない文字列ならともかく、ASCII範囲外の文字列すべてをエスケープしてしまうのはやり過ぎでしょう。

現代はUnicodeがあるおかげで、日本語に限らずともASCII範囲外の文字を扱うのは当たり前になりましたから。

Link to

here unicode-show を使おう

そこで便利なのがunicode-showです。

unicode-showの ushow 関数は、 show がエスケープシーケンスに変換した日本語などの文字列を、元の文字列に戻してくれます。

なので、新しい型クラスを定義する必要もなく、そのまま Show 型クラスのインスタンスを再利用できるのです。

早速先ほどの show を使った例に適用してみましょう。

まずは👇のコマンドでインストールして、GHCiを起動します。

Text.Show.Unicode モジュールを import して show を使っている箇所を ushow に変えれば、お望みどおりの挙動になります。

わくわくもんですね！

print の例も、 uprint に変えれば🆗です。

ウルトラハッピーですね！！

さらに、次のコマンドをGHCiに入力すれば、GHCiに直接入力した日本語文字列もそのまま表示されるようになります。

カンペキ✨

えっ、常に uprint したいからいちいち :set -interactive-print=uprint するのが面倒くさい？

そんなあなたは👇を ~/.ghci に書くことけって～いでしょう。

Link to

here unicode-show の最近の修正

そんなunicode-showですが、残念ながら一昨年、作者である村主崇行さんが亡くなってしまいました 。

日本に住むHaskellerをサポートする日本Haskellユーザーグループとしては、このパッケージをメンテナンスし続けることに大きな意義があると判断し、私はこのパッケージをHaskell-jpのGitHubリポジトリーでメンテナンスすることにしました。

以下がそのリポジトリーです。

https://github.com/haskell-jp/unicode-show

といっても、メンテナーの名前や LICENSE ファイルを書き換えて最新版をアップロードして以降特に何もしていなかったのですが （バグはあるけど直すのも難しそうだし、概ね使えるし） 、なんと先日、Pull requestが来ました！

Do not show values eagerly by Kaiepi · Pull Request #4 · haskell-jp/unicode-show

この修正を適用する前のunicode-showは、文字列全体を評価してからエスケープシーケンスを元に戻す、という挙動だったため、長い文字列を与えた場合や無限の長さの文字列を与えた場合に、なかなか （あるいは永遠に） 結果が返ってこないという問題がありました。

修正後はちゃんと遅延評価を利用することで、無限の長さの文字列でも少しずつ変換することができます。

今日記事にした一番の理由はこの話をするためです。

Kaiepiさんありがとうございます！

先ほどリリースしました！🎉

http://hackage.haskell.org/package/unicode-show-0.1.0.4

Link to

here pretty-simple も使おう

時間がないので詳しくは省略しますが、実はpretty-simpleというパッケージを使えば、日本語をそのまま出力するのに加えて、プリティープリントできます。

例ではわかりづらいですが、ちゃんと色も着けてくれます！

それでは2020年も、Happy Haskell Hacking🎁