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#にスイッチしました。
使い勝手は?
HaskellやScala(shapeless)のそれに比べると使い勝手は悪いかもしれません…というかまず機能の差が。 それに彼らはこちらにはないHTやマクロ、型クラスがありますからね。
これは完全に型推論の力に依存して使いやすさが変わります。 サンプルコードを見ればその違いがよくわかるので、いかにリンクを並べておきます。
- Java https://github.com/functionaljava/functionaljava/blob/435cdac93bee544a93f5db9dabbaa0ec693e14e6/demo/src/main/java/fj/demo/HList_append.java#L13
- C# https://github.com/pocketberserker/Data.HList/blob/6db260b37d52764a9819fdc1c0918b6c47ee26ee/examples/HList.CSharpExamples/Program.cs#L10
- F# https://github.com/pocketberserker/Data.HList/blob/6db260b37d52764a9819fdc1c0918b6c47ee26ee/FSharp.Data.HList.Tests/HListTest.fs#L22
HAppendの例だけなのと、C#の実装がこれでよいのか自信がないのであれですが、C#...。
Javaは変数の型を書くのはだるいものの、型は比較的わかりやすいためそんなに考えなくてもなんとかなります。 が、C#はメソッドのほうが推論されないため、4つの型パラメータに何を当てはめれば望みの型になるのか考える必要があります。 F#もC#と同じ道をたどるかと思いきや…この程度のコードだと空気を読んで型を推論してしまいます*1。
まとめ
*1:推論に頼りすぎると前述みたいな型エラー事案に遭遇するのでご利用は計画的に