2

I'm new to Scala...

Anyway, I want to do something like:

val bar = new Foo("a" -> List[Int](1), "b" -> List[String]("2"), ...)
bar("a") // gives List[Int] containing 1
bar("b") // gives List[String] containing "2"

The problem when I do:

class Foo(pairs: (String, List[_])*) {
  def apply(name: String): List[_] = pairs.toMap(name)
}

pairs is gonna be Array[(String, List[Any]) (or something like that) and apply() is wrong anyway since List[_] is one type instead of "different types". Even if the varargs * returned a tuple I'm still not sure how I'd go about getting bar("a") to return a List[OriginalTypePassedIn]. So is there actually a way of doing this? Scala seems pretty flexible so it feels like there should be some advanced way of doing this.

2 Answers2

2

No.

That's just the nature of static type systems: a method has a fixed return type. It cannot depend on the values of the method's parameters, because the parameters are not known at compile time. Suppose you have bar, which is an instance of Foo, and you don't know anything about how it was instantiated. You call bar("a"). You will get back an instance of the correct type, but since that type isn't determined until runtime, there's no way for a compiler to know it.

Scala does, however, give you a convenient syntax for subtyping Foo:

object bar extends Foo {
  val a = List[Int](1)
  val b = List[String]("2")
}
Chris Martin
  • 30,334
  • 10
  • 78
  • 137
1

This can't be done. Consider this:

val key = readStringFromUser();
val value = bar(key);

what would be the type of value? It would depend on what the user has input. But types are static, they're determined and used at compile time.

So you'll either have to use a fixed number of arguments for which you know their types at compile time, or use a generic vararg and do type casts during runtime.

Petr
  • 62,528
  • 13
  • 153
  • 317