日本語をshowしてうまく表示されなかったら

unicode-showの紹介(と、pretty-simpleを少し)

Posted by YAMAMOTO Yuji(@igrep) on December 22, 2019Tags: 日本語

Link to
here
ℹ️この記事は🎄

この記事は、Haskell Advent Calendar 2019 22日目の記事です。
例年どおりタイプセーフプリキュア!の話をするつもりでしたが、ネタが実装できなかったのでunicode-showの話をします1
まぁ、こちらの方がみなさんにとっては有益でしょうし🙃

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-showushow関数は、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ですが、残念ながら一昨年、作者である村主崇行さんが亡くなってしまいました2
日本に住むHaskellerをサポートする日本Haskellユーザーグループとしては、このパッケージをメンテナンスし続けることに大きな意義があると判断し、私はこのパッケージをHaskell-jpGitHubリポジトリーでメンテナンスすることにしました。
以下がそのリポジトリーです。

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🎁


  1. 例年どおりですとプリキュアAdvent Calendarと同時投稿をしている予定でしたが、例年参加者が減っていたこともあり、今年はプリキュアAdvent Calendarはなくなってしまいました😞

  2. 村主崇行さんは「すごいHaskellたのしく学ぼう!」の翻訳を担当されるなど、unicode-show以外にも日本のHaskell界に多大な功績をもたらした方でした。