在Scala中包装重载函数(可能使用宏)

时间:2014-11-03 19:04:14

标签: scala overloading scala-macros

假设我有类型ABC以及重载方法:

def foo(a: A): C
def foo(b: B): C

然后假设我有一个(复杂的)代码片段,它适用于C类型的对象。我想要的是一种采用AB类型的方法:

def bar(x: [A or B]) = {
  val c = foo(x)
  // Code that works with c
}

当然,我可以编写两个版本的bar,重载以获取类型AB,但在这种情况下,有多个函数的行为类似于bar ,对于所有这些版本,重载版本(在我的实际情况下,有foo的三个版本)是愚蠢的。

C风格的宏在这里会很完美,所以我想看看Scala宏。尴尬的部分是Scala宏仍然是经过类型检查的,所以我不能说

reify(foo(x.splice))

因为编译器想要事先知道x的类型。我是使用Scala宏的全新手段(而且它是一个实质性的API),所以在这方面的一些指示将不胜感激。

或者,如果有一种方法可以在没有宏的情况下布置此代码,那也会有所帮助!

1 个答案:

答案 0 :(得分:1)

您可以采用不同的方式解决问题。

而不是说A or B类型,而不是从这些类型中想出你想要什么。在你的例子中,如果你说:“只要我有一个foo方法,它就是什么类型并不重要”。这就是下面的代码所示:

trait FooMethod[T] {
  def apply(t:T):C
}

object FooMethod {
  implicit val forA = new FooMethod[A] {
    def apply(a:A):C = foo(a)
  }

  implicit val forB = new FooMethod[B] {
    def apply(b:B):C = foo(b)
  }
}

def bar[X](x: X)(implicit foo:FooMethod[X]) = {
  val c = foo(x)
  // Code that works with c
}