- Learning Functional Programming in Go
- Lex Sheehan
- 436字
- 2025-02-27 05:14:35
A closer look at currying
Before we move on, let's look at the following curried versus non-curried code example to improve our understanding of currying:
package main
import "fmt"
// numberIs numberIs a simple function taking an integer and returning boolean
type numberIs func(int) bool
func lessThanTwo(i int) bool { return i < 2 }
// No curried parameters
func lessThan(x int, y int) (bool) {
return x < y
}
func main() {
fmt.Println("NonCurried - lessThan(1,2):", lessThan(1, 2))
fmt.Println("Curried - LessThanTwo(1):", lessThanTwo(1))
}
You would immediately see that the curried example takes only one parameter, whereas the non-curried example requires two. The idea behind currying is to create new, more specific functions from smaller, more general, functions by partially applying them. We'll see more of this in Chapter 8, Functional Parameters.
Another take away is the use of a function type. The numberIs is a data type that is a function that takes an int and returns a bool. That's right. In FP, we are not scared of functions. We treat them as a regular old data type. In FP everything is data, and data never changes. It only gets passed around, created and returned.
The value of angle x is equal to the length of the (A)djacent side pided by the length of the (H)ypotenuse (http://www.mathopenref.com/cosine.html):
cos x = A / H

In imperative programming, we are led to believe that functions and data are different things. In FP, we see that functions have no side effects. A good FP example is the geometric cosine function. For a right-angle triangle, if we pass 15 for the (A)djacent side and 30 for the (H)ypotenuse, then we get 0.5 as the cosine of angle A. Since we can rely on that fact--pass 15 and 30 and get 0.5 every time--even with our imperative programming hats on, we know we can put those values in a lookup table. Imagine a spreadsheet where row numbers represent the A's and the columns represent the H's. The cell at row 15, column 30, would have the value 0.5.
See, functions are data! However, we don't always want to store every computed value for every possible parameter combination in every use case, just where it makes sense to do so.
Imagine the performance of a system where every function call is a table lookup. Now imagine our reuse potential, where the evaluation parts of the applications are generic. If your mind is still intact, wait until Chapter 9, Category Theory That Applies, where we will discuss the application of category theory and type classes.