定义具有可变返回类型的函数的scala Map

时间:2015-11-11 09:13:32

标签: scala

是否可以将具有变量返回类型的函数Map的返回类型概括为公共签名,然后在运行时使用Map中每个函数的实际返回类型?

说明:

我有一个字符串的scala Map - >功能定义为:

Map[String, (String) => Seq[Any]] = Map("1" -> foo, 2 -> bar, 3 -> baz)

其中foo,bar和baz定义为:

foo(string: String): Seq[A]
bar(string: String): Seq[B]
baz(string: String): Seq[C]

编译工作正常,但在运行时,函数返回的Seq [A或B或C]类型被视为Seq [Any],从而给出了反射异常。

2 个答案:

答案 0 :(得分:1)

我想你可以试试这个变种

def foo(string: String): Seq[String] = {
 Seq(string)
}

def bar(string: String): Seq[Int] = {
 Seq(1)
}
val map = Map(1 -> foo _, 2 -> bar _)
val res = map(1) match {
    case f: (String => Seq[String]) => f
    case f: (String => Seq[Int]) => f
    case _ => throw new NotImplementedError()
}

println(res("Hello"))

它适用于我。

答案 1 :(得分:1)

让我们想象一些类似Map的解决方法

假设我们定义类似

的类型
import scala.reflect.runtime.universe._

class PolyMap[K, V[+_]] {
  var backing = Map[(K, TypeTag[_]), V[Any]]()

  def apply[T: TypeTag](key: K) =
    backing.get(key, typeTag[T]).asInstanceOf[Option[V[T]]]

  def update[T: TypeTag](key: K, f: V[T]): this.type = {
    backing += (key, typeTag[T]) → f
    this
  }
}

现在有了

type String2Seq[+X] = String ⇒ Seq[X]
val polyMap = new PolyMap[String, String2Seq]

polyMap("foo") = foo
polyMap("bar") = bar

你可以确保

polyMap[String]("foo").map(_("x")) == Some(foo("x"))
polyMap[Int]("foo").map(_("x")) == None
polyMap[Int]("bar").map(_("x")) == Some(bar("x"))