• 作成:

第6回Haskell-jpもくもく会@朝日ネットに参加してきました, overloaded-recordsライブラリを読みました

(学生は懇親会無料!)第6回Haskell-jpもくもく会 @ 朝日ネット - connpass

開場は12:50なのだからその時に到着するようにすればよかったですね. 開催時間の13:00に合わせてしまいました.

なので自己紹介の時間を逃したと思っていたのですが, 13:45分ほどに始まったので良かったです.

今回はGenericやTemplate Haskellを使ったことがないので, それでボイラープレートのコードを自動的に生成するという試みをしてみようと思っています. 具体的には重複したフィールドラベル - あどけない話に書かれているようなIsLabelinstanceの定義の生成をやりたい. 既に行われているかもしれませんが…

と思ってあらためて調べなおしてみたらoverloaded-records :: Stackage Serverの, Data.OverloadedRecordsに考えているようなものが存在していることがわかりました. この前に調べた時は見つけられませんでした.

私が考えているのはDuplicateRecordFieldsを前提とするものなので, 少し違うような気がしますね.

Data.OverloadedLabelsData.OverloadedRecordsでは実装されているものが違うことがわかってきました. Data.OverloadedLabelsRecords/OverloadedRecordFields/OverloadedLabels – GHCに従って作られたもので, GHC.OverloadedLabelsと同じものです. というかData.OverloadedLabelsはGHC >= 8.0.1だとGHC.OverloadedLabelsをre-exportするみたいですね.

Data.OverloadedRecordsDuplicateRecordFieldsを想定せずに, アンダーバーやタイプやコンストラクタの名前から取ったプレフィクスを取り除いたラベルを定義してくれるようですね. 具体的にはdefaultMakeFieldNameでプレフィクスを削除してくれます.

私はパターンマッチを簡潔にしたいと思っていて, そのためにはDuplicateRecordFieldsが良い感じだと思って使っていたのですが, overloaded-recordsはプレフィクスを付けてラベルで取り外すという方針のようです. プレフィクスが付いていないカラムではNothingを返してラベルは生成されないようですね. なので, data Point2 = Point2{x :: Int, y :: Int}のようなデータ型にこれは使えません.

またData.OverloadedRecords#x pのようにはラベルを使わずに, get #x pのようにget関数を使ってラベルを使って値を取り出すようです. ラベルをどう使っても自由ですが, この設計はRecords/OverloadedRecordFields/OverloadedLabels – GHCに反しているのでは? と思って書いてみたら#x pでもget #x pでもどちらでも良いようです. 勘違いしました.

自分の理想とするものはDuplicateRecordFieldsを使えるものなので, やはり自分で書こうかと思いましたが, 自分で書いてもoverloaded-recordsの縮小版になってしまうことが予想されます. それならば, pull requestを出してDuplicateRecordFieldsに対応させれば良いと思いました.

overloaded-recordsのtravis.ymlを見てみたら, ghc-7.8.4をサポートしていることがわかりました. なるほど, DuplicateRecordFieldsはghc-8からの機能なので, それでサポートしていなかったんですね. しかし, ghc-7を使っていて最新版ライブラリを使いたいという人は少ないでしょうし, 思い切ってghc-7のサポートを切り捨てたpull requestを出す方針で行こうと思いました.

defaultMakeFieldNameを少し書き換えてデータ型のプレフィクスがない場合もそれをそのまま返してやれば良いだけだと思ったのですが, 話がそんなに単純ではないことがわかってきました. DuplicateRecordFieldsを使った場合, 重複するレコード名にモジュール名のプレフィクスが付くので, それを取り除く必要があります. これは既存のコードを使うより自分で書いたほうがまだ楽そうな気がしてきました, 既存のコードは古いコンパイラ対応のためのプリプロセッサもかなり多いですし.

よく考えたら元々はTemplate Haskellを勉強するためという目的があったはずなので, やはり自分で書いてみようとしようとしたのですが, Template Haskellをほとんど把握していなかったので, 中々進まず時間が終了しました. じっくりやれば出来そうな気もしますが, 真面目にやらないと難しそうですね.

時間中はGHCの提案やoverloaded-recordsのソースを読むばかりでしたが, Haskellに詳しくなれたのは普通に良いことですし, overloaded-recordsのソースを読むことで当初の目標であるTemplate Haskellに詳しくなるという目標は多少達成できたと思います

発表の有限体の話は私に数学的知識が不足しているせいで正直言って今ひとつ理解ができませんでしたが, Haskellの代数的データ型と型クラスと中置演算子の機能を活かしているということはわかりました.

終わった後は懇親会に行ってきました. 学生枠なので無料でした, ありがとうございます! 普段は周りにHaskellが出来る人なんて殆どいないので, 何の話をするにしてもHaskellという共通の知識があるというのは新鮮でした. 圏論などの話も出てインターネット感(?)がありました.