Заголовок пытается описать следующий подтип
implicitly[Map[Int, String] <:< Iterable[(Int, String)]]
Параметр типа A
выводится как (Int, String)
здесь
def foo[A](cc: Iterable[A]): A = cc.head
lazy val e: (Int, String) = foo(Map.empty[Int, String])
, однако пытается достичь аналогичного эффект с использованием границ параметра типа лучшее, что я могу сделать, это явное указание арности конструктора типа, например,
def foo[F[x,y] <: Iterable[(x,y)], A, B](cc: F[A, B]): (A, B) = cc.head
lazy val e: (Int, String) = foo(Map.empty[Int, String])
, потому что следующие ошибки:
def foo[F[x] <: Iterable[x], A](cc: F[A]) = cc.head
lazy val e: (Int, String) = foo(Map.empty[Int, String])
// type mismatch;
// [error] found : A
// [error] required: (Int, String)
// [error] lazy val e: (Int, String) = foo(Map.empty[Int, String])
// [error] ^
Следовательно, используя Iterable
в качестве верхней границы похоже, нам нужна одна подпись для обработки конструкторов унарных типов Seq
и Set
, и отдельная подпись для обработки конструкторов типов с двумя арностями Map
def foo[F[x] <: Iterable[x], A](cc: F[A]): A // When F is Seq or Set
def foo[F[x,y] <: Iterable[(x,y)], A, B](cc: F[A, B]): (A, B) // When F is Map
Есть ли способ иметь один подпись с использованием границ типа, которая работает для всех трех? Иными словами, как мы могли бы написать, скажем, метод расширения, который работал бы во всех коллекциях?