2015-06-18 97 views
0

我想了解功能部分應用如何在斯卡拉工作。斯卡拉功能部分應用

爲了做到這一點,我已經建立了這個簡單的代碼:

object Test extends App { 
    myCustomConcat("General", "Public", "License") foreach print 

    GeneralPublicLicenceAcronym(myCustomConcat(_)) foreach print 

    def myCustomConcat(strings: String*): List[Char] = { 
    val result = for (s <- strings) yield { 
     s.charAt(0) 
    } 

    result.toList 
    } 


    def GeneralPublicLicenceAcronym (concatFunction: (String*) => List[Char]) = { 

    myCustomConcat("General", "Public", "License") 
    } 
} 

myCostumConcat功能在輸入採用一個String數組,它返回一個包含每個字符串的第一個字母列表。

所以,代碼

myCustomConcat("General", "Public", "License") foreach print 

將打印在控制檯上:GPL

現在我想編寫一個函數生成GPL的縮寫,使用(作爲輸入參數)我以前的假設函數提取每個字符串的第一個字母:

def GeneralPublicLicenceAcronym (concatFunction: (String*) => List[Char]): List[Char] = { 

    myCustomConcat("General", "Public", "License") 
    } 

用部分應用程序運行這個新函數:

GeneralPublicLicenceAcronym(myCustomConcat(_)) foreach print 

我得到這個錯誤:

錯誤:(8,46)型不匹配;找到:Seq [String] required:String GeneralPublicLicenceAcronym(myCustomConcat(_))foreach print

爲什麼?我可以在這種情況下使用部分申請嗎?

回答

3

所有你需要做的是改變myCustomConcat(_)myCustomConcat _,或甚至只是myCustomConcat

你在做什麼是不完全的部分應用程序 - 它只是使用方法作爲函數值。

在某些情況下(需要函數值),編譯器會計算出你的意思,但在其他上下文中,通常需要使用_後綴告訴編譯器你的意圖。

「局部應用」意味着我們正在給一個函數提供了一些,但不是所有的參數,創建一個新的功能,例如:

def add(x: Int, y: Int) = x + y   //> add: (x: Int, y: Int)Int 

    val addOne: Int => Int = add(1, _)  //> addOne : Int => Int = <function1> 

    addOne(2)         //> res0: Int = 3 

我想你的情況可能被視爲局部應用,但應用沒有的參數 - 你可以在這裏使用部分應用程序的語法,但你需要給一個_*提示,因爲重複的參數的編譯器(String*),從而結束了一個有點難看:

myCustomConcat(_:_*) 

另請參閱:Scala type ascription for varargs using _* cause error