私は、異なる(しかしそれぞれが同種の)タイプのトラバーサブルの複数の外積を構築しようとしています。必要な戻り値の型は、入力トラバーサブルの型と一致する型を持つタプルのトラバーサブルです。例えば:
List(1, 2, 3) cross Seq("a", "b") cross Set(0.5, 7.3)
これTraversable[(Int, String, Double)]
により、3 つのソースから可能なすべての組み合わせが得られます。2 つのソースのみを組み合わせる場合は、ここで適切に回答されています。与えられたアイデアは次のとおりです。
implicit class Crossable[X](xs: Traversable[X]) {
def cross[A](ys: Traversable[A]) = for { x <- xs; y <- ys } yield (x, y)
}
そこのコメントは、より多くのソースの問題について簡単に言及していますが、私は shapeless にも scalaz にも依存しない解決策を探しています (一方で、 にスケールアップするためのボイラープレートがいくつかあることは気にしませんTuple22
)。私がやりたいことは、次のようなものです。
implicit class Crossable[X](xs: Traversable[X]) {
def cross[A](ys: Traversable[A]) = for { x <- xs; y <- ys } yield (x, y)
def cross[A,B](ys: Traversable[(A,B)]) = // ... extend all Tuple2's in ys with x in xs to Tuple3's
def cross[A,B,C](ys: Traversable[(A,B,C)]) = // ...
// ...
}
これは、型の消去のために明らかに機能しません (そして、残念ながら、上記の例ではおそらく括弧を使用する必要がありますcross
。右結合になるからです)。
私の質問は、Scala 2.10 のリフレクション機能を利用して問題を解決することは可能ですか? A
一般に、 と の両方をさまざまなタプル型 (およびそれらの型パラメーター、これは難しいようです)に一致X
させ、それらをより大きなタプルにマージすると、結合法則を満たす解決策が得られるはずですよね?