Subscribed unsubscribe Subscribe Subscribe

Parsec 3活用事例: Keepalived構文チェッカ

お台場のTOKYO CULTURE CULTUREで開かれたHaskellナイトというイベントで、ライトニングトーク「Haskellゴング」に出てでしゃべってきた。

ソースコードはgithubで。

Parsec 3からモナド変換子の実装が入ったことで、パーザ内部でI/Oすることができるようになったため、include文のパーズが簡単になったというお話。text-keepalivedの方は仕事で使っています。アルバイトも募集しています。

Parsec 2に関する補足

id:kazu-yamamotoさんから質問を受けたので、補足を書いておきます。

以前のParsec 2ではパーザの型は

type Parser a = GenParser Char () a

で、GenParser tok stがMonadインスタンスになっています。これに対するモナド変換子な実装はないので、include文のようにパーズしていく中で外部のファイルへのI/Oが必要になっても、残念ながらできません。

これを回避するには、たとえば

  • あらかじめincludeの内容を展開しておく前処理をする
    • これはうまくやらないと、エラーメッセージのポジションが出せなくなる
  • includeの手前までパーズして、includeは別にパーズ、続きはまた別にパーズみたいに分ける
    • これは解析結果が単なるリストならうまくいくけど、木構造の一部だったりするとうまくいかないかもしれない?
  • あらかじめincludeされる全ファイルをパーズしておく、それで解析結果を大本のファイル用のパーザに渡す
    • いかにも効率が悪そう

とかとか、面倒そうな操作をしないとダメなのではないかと思います。面倒そうで試していませんが。

これが、Parsec 3からはパーサの型が

type Parsec s u = ParsecT s u Identity

となって、このParsecT s uがMonadTransのインスタンスになっています。Parsec型ではなくParsecTをそのまま使うと、ベースのモナドになっているIdentityを自由に変えることができて、パーズ中にliftIOを使うとI/Oができるようになり、面倒なことをせずinclude文に対応できるようになりました。

イベントの感想

邦訳が立て続けに2冊来て、2-3年くらい前?にあったHaskellプチブームがまた来ているのかなあという印象。個人的にはまだまだ広く広まる気は全くしていなくて、キラーアプリができるまでは今の状態のまま定期的にプチブームが来ては去ってを繰り返しそうな気がする。有料イベント会場での「練習問題以上のプログラムを書いたことがあるか」の問いに対して、ぽつぽつしか手が上がらなかったのが現状をよく表していると思う。

ただ邦訳が出たことで良質な日本語ドキュメントが一気に増えたので、裾野は広がっていきそう。

Haskellゴングに関しては、id:tanakhさんのMonadPointが実用的で良かった。ニコニココメント機能もちゃんと動いていた。近日github公開予定らしいので期待。あとはsakaiさんのPTQの話はこういう世界があるのかあと感心した。

あと、やはりネットワーク周りなどI/Oの多いプログラムの書きにくさが課題になっている印象。関数的なI/OはFRPで解決できそうな気がするんだけど調べてない。そろそろFRPをちゃんと理解したいなー。

最後に、イベント関係者のみなさまお疲れ様でした。ごちそうさまでした。