0
votes

In a project I am working on, I often find myself converting a List[(A, List[B])] into a List[(A, B)] where every a in A is paired with every b in B in its corresponding pair.

I have written the following Scala method to achieve this.

object Loop {
  def unroll[A, S <: Seq[B], B](in: Seq[(A, S)]) : Seq[(A, B)] =
    in.flatMap(inPair => inPair._2.map(c => inPair._1 -> c))
}

When I attempt to use this intuitively as

Loop.unroll(List[Pair[Int, List[String]]](1->List("1", "2")))

I get a compiler argument stating

inferred type arguments [Int, List[String], Nothing] do not conform to method unroll's type parameter bounds [A, S<: Seq[B],B].

I can fix this by parameterizing unroll as

unroll[Int, List[String], String](...)

however aesthetically I feel like the 3rd string parameter is redundant. If possible, how can I rewrite this to either not require the 3rd type parameter or allow scala's type inferencing to guess it? I am using scala 2.9.3.

1

1 Answers

1
votes

Try this:

  def unroll2[A, B](in: Seq[Pair[A, Seq[B]]]): Seq[(A, B)] = {
    in.flatMap(pair => pair._2.map(v => pair._1 -> v))
  }

  val unrolled: Seq[(Int, String)] = unroll2(List(1 -> List("A", "B")))

Also to make the types less complicated I'd consider using a Map[A, Seq[B]]