2017-02-01 59 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") 
    }} 
}