Scala中Currying问题:求使语句编译通过的三种类型
嗨,作为Scala新手,柯里化确实容易让人懵,我先给你掰扯明白这个概念,再结合具体例子给你三种能编译通过的类型,保证你能看懂~
柯里化本质上是把接受多个参数的函数拆成一系列只接受单个参数的函数链。举个直白的例子:
- 普通多参数函数:
def add(a: Int, b: Int) = a + b,调用方式是add(1,2) - 柯里化函数:
def add(a: Int)(b: Int) = a + b,调用方式是add(1)(2)
中间的核心区别是:当你调用add(1)的时候,并没有直接得到结果,而是得到了一个新的小函数——这个小函数专门等着接收第二个参数b,等你传了b之后才会计算最终结果。这种拆分方式很灵活,能实现「部分应用」(比如先固定第一个参数,得到一个专属的加法函数)。
假设你的柯里化函数是下面这种通用结构(很多新手入门时会写类似的代码):
// 柯里化函数:先接收类型A的参数,再接收类型B的参数,返回类型C的结果 def myCurriedFunc[A, B, C](first: A)(second: B): C = { (first, second) match { case (i: Int, s: String) => s"数字$i 搭配字符串$s" case (list: List[_], elem: Any) => list :+ elem case (b1: Boolean, b2: Boolean) => b1 && b2 } }.asInstanceOf[C]
下面是三种能让这个函数编译通过的类型组合,每个都带详细解释:
1. A: Int, B: String, C: String
调用代码:
val result1: String = myCurriedFunc(42)("Scala入门指南")
解释:
第一个参数传Int类型的42,第二个传String类型的"Scala入门指南",函数内部会匹配到Int + String的分支,返回拼接后的字符串,完全符合C: String的类型要求,编译毫无问题。从柯里化的角度看,myCurriedFunc(42)会返回一个专门等待接收String参数的函数,传入字符串后才会生成最终结果。
2. A: List[Int], B: Int, C: List[Int]
调用代码:
val result2: List[Int] = myCurriedFunc(List(1,2,3))(4)
解释:
第一个参数是List[Int]类型的列表,第二个是Int类型的元素,函数内部会把元素添加到列表末尾,返回新的List[Int],和我们指定的C类型完全匹配。这里柯里化的优势很明显:你可以先调用myCurriedFunc(List(1,2,3))得到一个「专门给这个列表加元素」的函数,之后随时给它传不同的Int元素,就能快速生成新列表,非常灵活。
3. A: Boolean, B: Boolean, C: Boolean
调用代码:
val result3: Boolean = myCurriedFunc(true)(false)
解释:
两个参数都是Boolean类型,函数内部执行逻辑与操作,返回Boolean结果,完全匹配类型声明。利用柯里化的特性,你还可以先固定第一个布尔值,比如写val andWithTrue = myCurriedFunc(true)_(下划线表示「我要部分应用这个函数,先不传第二个参数」),之后andWithTrue(false)会直接返回false,andWithTrue(true)返回true,相当于生成了一个专属的「与true做逻辑与」的工具函数。
内容的提问来源于stack exchange,提问作者saydak

