Functional Java の HList を C# に移植して F# 拡張を作った

前々からFunctional JavaにHListが存在するのは知っていたのですが、なかなか手をだせていませんでした。 で、最近Lensライブラリ移植の息抜きにちょっと時間があったので移植してみました。

そもそもHListって?

heterogenous list。 日本語ではたまにヘテロリストとも呼ばれてるみたいですね。 "haskell HList"とか"HList shapeless"で検索すれば何かしら情報は手に入ると思います。

というわけで作った

下記リポジトリから取得できいます。 NuGetにも公開しているので簡単に試すこともできます。

pocketberserker/Data.HList · GitHub

移植自体はそんなに難しくなかった…嘘ですごめんなさい。

実は最初は Pure F# で実装していたのですが、型推論がだめな方向に作動してしまって型エラーをなんとかするのが面倒になった経緯があります。 以下残骸。

Pure F# で HList を実装しようとしたが…型推論に阻まれる

Apply.Cons に型を書けば問題なく通るかもですが、それやるのであればいっそもうC#で実装したほうがいいんじゃない、ということでC#にスイッチしました。

使い勝手は?

HaskellScala(shapeless)のそれに比べると使い勝手は悪いかもしれません…というかまず機能の差が。 それに彼らはこちらにはないHTやマクロ、型クラスがありますからね。


気をとりなおして、JavaC#とF#の使い勝手について。

これは完全に型推論の力に依存して使いやすさが変わります。 サンプルコードを見ればその違いがよくわかるので、いかにリンクを並べておきます。

HAppendの例だけなのと、C#の実装がこれでよいのか自信がないのであれですが、C#...。

Javaは変数の型を書くのはだるいものの、型は比較的わかりやすいためそんなに考えなくてもなんとかなります。 が、C#メソッドのほうが推論されないため、4つの型パラメータに何を当てはめれば望みの型になるのか考える必要があります。 F#もC#と同じ道をたどるかと思いきや…この程度のコードだと空気を読んで型を推論してしまいます*1

まとめ

  • C#とF#でもHList使えるよ!
  • 本記事とは若干関係ないけど、HListはジェネリクスの勉強に役立つ(要出典、要検証)
  • FoldrのF#拡張とサンプルを作りたい人生
  • map関数を作りたい

*1:推論に頼りすぎると前述みたいな型エラー事案に遭遇するのでご利用は計画的に