Я пытаюсь построить несколько перекрестных произведений обходов разных (но каждый однородных) типов. Желаемый возвращаемый тип — это обход кортежа с типом, соответствующим типам во входных обходах. Например:
List(1, 2, 3) cross Seq("a", "b") cross Set(0.5, 7.3)
Это должно дать Traversable[(Int, String, Double)]
со всеми возможными комбинациями из трех источников. Случай объединения только двух источников был хорошо рассмотрен здесь. Данная идея такова:
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
с различными типами кортежей (и параметрами их типов, что кажется сложной задачей) и объединение их с более крупными кортежами должно обеспечить решение, удовлетворяющее ассоциативному закону, верно?