跳转到内容

Scala/柯里化

来自维基教科书,开放的书籍,开放的世界

来自维基百科:在w:数学w:计算机科学 中,柯里化 [schönfinkeling[1][2]] 是一种将接受多个参数(或参数元组)的函数转换为可被调用为一系列单参数函数链的函数的技术(w:部分应用)。它最初由 w:莫里斯·肖恩芬克尔[3]提出,后来由 w:哈斯凯尔·卡里完善。[4][5]

函数式语言允许使用柯里化对函数进行部分应用,例如我们可以柯里化运算符

def * = (a:Int) => (b:Int) => a * b
val timesthree = *(3)
timesthree(4)

timesthree(4) 的结果将是 12。

这允许通过仅传递柯里化函数需要的一些参数来轻松地定义新函数。这些函数是普通函数,可以在任何其他高阶函数中使用(例如 map)。

以下是柯里化函数定义和调用的几个示例

object smallExamples {
  
  def currysum(x:Int)(y:Int)(z:Int) = x + y + z
  
  val currysum2 = (x: Int) => (y: Int) => (z: Int) => x + y + z
  
  val currysum3: Int => Int => Int => Int = x => y => z => x + y + z
  
  def nocurrysum(x:Int, y:Int, z:Int) = x + y + z
  
  val currysum4 = (x: Int) => (y: Int) => (z: Int) => nocurrysum(x, y, z) 

  def main(args: Array[String]): Unit = {
      val res = (smallExamples currysum 2)(3)(4)
      val res2 = (smallExamples currysum2 2)(3)(4)
      val res3 = smallExamples.currysum3(2)(3)(4)
      val res4a = (smallExamples currysum4 2)
      val res4b = res4a(3)
      val res4 = res4b(4)
      val res5 = smallExamples.nocurrysum(2, 3, 4)
      val resno = ((smallExamples.nocurrysum(2, _:Int, _:Int))(3, _:Int))(4)
      println(res)
      println(res2)
      println(res3)
      println(res4)
      println(res5)
      println(resno)
    }
}

请注意,函数 nocurrysum 不是柯里化的,但我们可以通过指定空参数(_)来创建柯里化函数,从而指示它们的类型。

参考文献

[编辑 | 编辑源代码]
  1. Reynolds, John C. (1998). "Definitional Interpreters for Higher-Order Programming Languages". Higher-Order and Symbolic Computation. 11 (4): 374. doi:10.1023/A:1010027404223. 在最后一行,我们使用了一种称为柯里化(以逻辑学家 H. Curry 命名)的技巧来解决在所有函数都必须接受单个参数的语言中引入二元运算符的问题。(裁判评论说,虽然 "柯里化" 更美味,但 "Schönfinkeling" 可能更准确。) {{cite journal}}: 无效的 |ref=harv (帮助)
  2. Kenneth Slonneger 和 Barry L. Kurtz. Formal Syntax and Semantics of Programming Languages. p. 144.
  3. Strachey, Christopher (2000). "Fundamental Concepts in Programming Languages". Higher-Order and Symbolic Computation. 13: 11–49. doi:10.1023/A:1010000313106. 有一个由 Schönfinkel 发明的设备,用于将具有多个操作数的运算符简化为对单个操作数运算符的连续应用。 {{cite journal}}: 无效的 |ref=harv (帮助) (转载自 1967 年的讲义。)
  4. Henk Barendregt, Erik Barendsen, "Introduction to Lambda Calculus", March 2000, page 8.
  5. Curry, Haskell (1958). Combinatory logic. Vol. I (2 ed.). Amsterdam, Netherlands: North-Holland Publishing Company. {{cite book}}: 未知参数 |coauthors= 被忽略 (|author= 建议) (帮助)
华夏公益教科书