跳轉到內容

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= 建議) (幫助)
華夏公益教科書