Scala/Currying

From Wikibooks, open books for an open world
Jump to: navigation, search

From wikipedia: In w:mathematics and w:computer science, currying [schönfinkeling[1][2]] is the technique of transforming a function that takes multiple arguments (or a w:tuple of arguments) in such a way that it can be called as a chain of functions, each with a single argument (w:partial application). It was originated by w:Moses Schönfinkel[3] and later worked out by w:Haskell Curry.[4][5]

Functional languages allow the partial application of functions with currying, for example we can currify operators:

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

And the result of timesthree(4) will be 12.

This allows defining new functions easily by passing only some of the arguments that the curried function needs. These functions are normal functions that can be used in any other higher order function (e.g. map).

Here are some examples of curried function definitions and invocations:

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)
    }
}

Note that the function nocurrysum is not curried but we can create a curried function by specifying an empty parameters (_) indicating their type.

References[edit]

  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. "In the last line we have used a trick called Currying (after the logician H. Curry) to solve the problem of introducing a binary operation into a language where all functions must accept a single argument. (The referee comments that although “Currying” is tastier, “Schönfinkeling” might be more accurate.)". 
  2. Kenneth Slonneger and 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. "There is a device originated by Schönfinkel, for reducing operators with several operands to the successive application of single operand operators.".  (Reprinted lecture notes from 1967.)
  4. Henk Barendregt, Erik Barendsen, "Introduction to Lambda Calculus", March 2000, page 8.
  5. Curry, Haskell; Feys, Robert (1958). Combinatory logic. I (2 ed.). Amsterdam, Netherlands: North-Holland Publishing Company.