我试图了解函数部分应用程序在Scala中是如何工作的。
为此,我已经构建了这个简单的代码:
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)类型不匹配; found:Seq [String] required:String GeneralPublicLicenceAcronym(myCustomConcat(_))foreach print
为什么呢?在这种情况下我可以使用部分申请吗?
答案 0 :(得分:3)
您需要做的就是将myCustomConcat(_)
更改为myCustomConcat _
,或者只改为myCustomConcat
您正在做的事情并非完全是部分应用 - 它只是使用方法作为函数值。
在某些情况下(预期函数值),编译器会找出你的意思,但在其他情况下,你经常需要使用_
后缀告诉编译器你的意图。
&#34;部分申请&#34;意味着我们正在为函数提供一些但不是全部的参数来创建一个新函数,例如:
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
我认为您的案例可以被视为部分应用程序,但应用 none 参数 - 您可以在此处使用部分应用程序语法,但您需要提供{ {1}}由于重复的参数(_*
)提示编译器,这最终有点难看:
String*