2017-02-01 16 views
-1

关于SO上的这个错误消息有几个问题,但他们似乎都没有涉及到这个问题。Scala论据过载中的匿名函数的类型

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可以清楚地看到我与字符串匹配,但无法推断出参数类型。

回答

1

这里的麻烦是有两个apply方法。如果只有一个:

object Block { 
    def apply(f: String => Bool) = ??? 
} 

然后一切都会正常工作,如斯卡拉将看到应用程序,并立即了解所需类型的匿名函数。然而,当存在两个或更多不同的方法:

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上一个线程过来:https://github.com/ReactiveX/RxScala/issues/160

1

如果你真的喜欢有两种不同的方法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") 
    }} 
}