对于通用类型的特殊情况,Scala方法重载

Edu*_*rdo 1 scala

我有以下方法:

def foo[A](x: =>A) = ???

def foo[B](x: =>WrapperType[B]) = ???
Run Code Online (Sandbox Code Playgroud)

这不会编译,因此很有意义,因为在第一种方法中,A也可以代表WrapperType[B]。我可以x在运行时检查类型,但似乎应该有一种在编译时执行此操作的方法。我该如何克服这个问题?

注意:上面的代码是我的真实代码的简化,它是:

def ifEmpty[B](errors:Seq[Error]*)(right: =>B): Either[Seq[Error], B] =
  if( areAllEmpty(errors) ) Right(right)
  else                      Left(errors.flatten)

def ifEmpty[C](errors:Seq[Error]*)(right: =>Either[Seq[Error], C]): Either[Seq[Error], C] =
  if( areAllEmpty(errors) ) right
  else                      Left(errors.flatten)
Run Code Online (Sandbox Code Playgroud)

som*_*ytt 5

这是消除签名歧义的常用方法(hack):

scala> :pa
// Entering paste mode (ctrl-D to finish)

object Y {
def f[A](a: =>  A) = 1
def f[A](a: => Either[Exception, A])(implicit d: DummyImplicit) = 2
}

// Exiting paste mode, now interpreting.

defined object Y

scala> Y.f(42)
res0: Int = 1

scala> Y.f(Right(42))
res1: Int = 2
Run Code Online (Sandbox Code Playgroud)

您可以foo擦除相同的签名,因为参数已在后台转换为功能。

不过,对Scala而言,foo(Wrapper)比更为具体foo(A)

您的示例真实代码无法工作,因为它是双重定义:重载仅考虑第一个参数列表。

编辑:不要这样测试