重载中匿名函数的Scala参数类型

重载中匿名函数的Scala参数类型,scala,anonymous-function,overloading,Scala,Anonymous Function,Overloading,关于这个错误消息,有很多问题,但似乎没有一个是关于这个问题的 The argument types of an anonymous function must be fully known. (SLS 8.5) 有问题的代码块试图模拟Ruby的块功能,其额外好处是参数可以在过程中进行模式匹配 object Block { def apply(f: => Unit) = apply((_: String) => f) def apply(f: String => Uni

关于这个错误消息,有很多问题,但似乎没有一个是关于这个问题的

The argument types of an anonymous function must be fully known. (SLS 8.5)
有问题的代码块试图模拟Ruby的块功能,其额外好处是参数可以在过程中进行模式匹配

object Block {
  def apply(f: => Unit) = apply((_: String) => f)
  def apply(f: String => Unit) = ???
}
def example() = {
  Block { // Error!
    case "A" => println("First letter of the alphabet")
    case _   => println("Not the first letter of the alphabet")
  }
}

尽管在下一行,Scala可以清楚地看到我正在与字符串进行匹配,但它无法推断参数类型。

这里的问题是有两种
应用方法。如果只有一个:

object Block {
  def apply(f: String => Bool) = ???
}
然后一切都会正常工作,因为Scala会看到应用程序并立即了解匿名函数的所需类型。但是,当有两种或两种以上不同的方法时:

object Block {
  def apply(f: => Bool) = apply((_: String) => f)
  def apply(f: String => Bool) = ???
}
Scala无法从
apply
的应用程序中推断参数的类型,也无法从参数的类型中推断要使用的
apply
的应用程序,因此它陷入了循环。最简单的解决方案似乎是简单地重命名其中一个方法

object Block {
  def apply(f: => Unit) = apply((_: String) => f)
  def branchOff(f: String => Unit) = ???
}
现在打电话并不难

Block { println("This is a regular application.") }
Block.branchOff {
  case "A" => println("A is for aardvark")
  case "B" => println("B is for beaver")
  case _   => println("Huh?")
}
您不必指定任何类型参数,也不必为此指定任何显式参数


GitHub上的一个线程中有更多关于这方面的详细信息:。

如果您真的喜欢使用两种不同的
apply()
方法,那么您必须为推理引擎提供一些帮助

def example() = {
  Block{s:String => s match {
    case "A" => println("First letter of the alphabet")
    case _   => println("Not the first letter of the alphabet")
  }}
}