ジェネリクスあるのでコネコネしてみた。
たとえば int 二つをとる関数のカリー化関数は個別には簡単に書ける
func curry(f func(int, int) int, x int) func(int) int { return func(y int) int { return f(y, x) } }
これを、ジェネリクスを使って
func curry[R, X, Y any](f func(X, Y) R, x X) func(Y) R { return func(y Y) R { return f(x, y) } }
こう書くことはできる。リターンタイプが最初の型パラメータにするのは手癖です。
であれば
func curry1[R, X, Y any](f func(X, Y) R, x X) func(Y) R { return func(y Y) R { return f(x, y) } } func curry2[R, X, Y, Z any](f func(X, Y, Z) R, x X) func(Y, Z) R { return func(y Y, z Z) R { return f(x, y, z) } } // 変数名はミスっている func curry3[R, X, Y, Z, Z1 any](f func(X, Y, Z, Z1) R, x X) func(Y, Z, Z1) R { ....
こういうふうに増やしていくことはできる。そんな、と思ったけどそういえばこういう型定義よく見る気はしますね。マクロで増やしたりするといいのか。
メソッドのレシーバに型パラメータは使えなさそう
func (f func(X, Y) R) curry[R, X, Y any](x X) func(Y) R { return func(y Y) R { return f(x, y) } }
こういう書き方はできない。これができると便利なんだけどな。method must have no type parameters
と言われてしまう。そもそもレシーバに型パラメータ付きの型も指定できない。むーん。