Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between currying and higher-order functions

Tags:

scala

Looking at Programming in Scala (control abstraction) I saw these two examples that have the same effect:

1. Higher-Order Function

def withPrintWriter(file: File, op: PrintWriter => Unit) {
  val writer = new PrintWriter(file)
  try {
    op(writer)
  } finally {
    writer.close()
  }
}

2. Currying function

def withPrintWriter(file: File)(op: PrintWriter => Unit) {
  val writer = new PrintWriter(file)
  try {
    op(writer)
  } finally {
    writer.close()
  }
}

What is the difference between them? Can we always achieve the same result in both ways?

like image 872
igx Avatar asked Sep 16 '13 12:09

igx


People also ask

Is currying a higher-order functions?

Note that a curried function is necessarily a higher-order function, since it returns a function as its result.

What is difference between higher-order functions and callbacks?

Higher-Order Functions(HoF) and Callback Functions(CB) are different. Higher-Order Functions(HoF): A function that takes another function(s) as an argument(s) and/or returns a function as a value. Callback Functions(CB): A function that is passed to another function.

When would you use a currying function?

Currying is helpful when you have to frequently call a function with a fixed argument. Considering, for example, the following function: If we want to define the function error , warn , and info , for every type, we have two options. Currying provides a shorter, concise, and more readable solution.

When would you use a higher-order function?

Higher order functions are also commonly used to abstract how to operate on different data types. For instance, . filter() doesn't have to operate on arrays of strings. It could just as easily filter numbers, because you can pass in a function that knows how to deal with a different data type.


2 Answers

The concepts of higher-order functions and curried functions are generally used in an orthogonal way. A higher-order function is simply a function that takes a function as an argument or returns a function as a result, and it may or may not be curried. In general usage, someone referring to a higher-order function is usually talking about a function that takes another function as an argument.

A curried function, on the other hand, is one that returns a function as its result. A fully curried function is a one-argument function that either returns an ordinary result or returns a fully curried function. Note that a curried function is necessarily a higher-order function, since it returns a function as its result.

Thus, your second example is an example of a curried function that returns a higher-order function. Here's another example of curried function that does not take a function as an argument, expressed in various (nearly equivalent) ways:

def plus(a: Int)(b:Int) = a + b
def plus(a: Int) = (b: Int) => a + b
val plus = (a: Int) => (b: Int) => a + b
like image 87
Aaron Novstrup Avatar answered Oct 28 '22 07:10

Aaron Novstrup


Higher order functions are functions that either take functions as parameter or return functions or both.

def f(g: Int => Int) = g(_: Int) + 23

scala> f(_ + 45)
res1: Int => Int = <function1>

scala> res1(4)
res2: Int = 72

This is a higher order function, it takes a function as parameter and returns another function. As you can see, higher order functions are a pre-requisite for currying. The curry function looks like this:

def curry[A,B,C](f: (A,B) => C) = (a: A) => (b: B) => f(a,b)

scala> curry((a: Int, b: Int) => a+b)
res3: Int => (Int => Int) = <function1>

scala> res3(3)
res4: Int => Int = <function1>

scala> res4(3)
res5: Int = 6

So to answer your question: They are two different concepts, where the one (higher order functions) is the pre-requisit for the other (currying).

like image 30
drexin Avatar answered Oct 28 '22 08:10

drexin