2015-06-18 98 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