5

I see that Swift offers convenient syntax for declaring curried functions. The manual gives partial function application as an example of where curried function will come in handy.

Can someone give me an example where partial function application can be useful? I know this is a general functional programming concept, but an example in Swift would be most appreciated.

Don Stewart
  • 137,316
  • 36
  • 365
  • 468
Mihai Damian
  • 11,193
  • 11
  • 59
  • 81
  • Most common use is to repeatedly query a container of some sort. Apply the lookup function to the container, name that value, and you get to repeatedly apply it a slightly cheaper cost. – Don Stewart Jan 08 '15 at 13:05

1 Answers1

12

Suppose you frequently want to check a number, i, is a multiple of another value. What it might be a multiple of can change, but the rule for how to determine it is always the same: i % n == 0.

You might write a function like this:

func isMultipleOf(#n: Int, #i: Int) -> Bool {
    return i % n == 0
}

isMultipleOf(n: 2, i: 3)  // false
isMultipleOf(n: 2, i: 4)  // true

However, perhaps you find yourself frequently wanting to use this function with other "high-order" functions – that is, functions that take other functions as arguments, such as map and filter:

 let r = 1...10
 // use isMultipleOf to filter out the even numbers
 let evens = filter(r) { isMultipleOf(n: 2, i: $0) }
 // evens is now [2,4,6,8,10]

That use of isMultipleOf looks a little clunky and hard to read, so maybe you define a new function, isEven, in terms of isMultipleOf to make it a bit clearer:

let isEven = { isMultipleOf(n: 2, i: $0) }
isEven(2)  // true
isEven(3)  // false
let evens = filter(r, isEven)

Now, suppose you declare isMultipleOf a little differently, as a curried function:

func isMultipleOf(#n: Int)(#i: Int) -> Bool {
    return i % n == 0
}

isMultipleOf is now a function that takes a number, n, and returns a new function that takes a number and checks if it's a multiple of n.

You can now use it to declare isEven like this:

let isEven = isMultipleOf(n: 2)

Or you could use it directly with filter like this:

let evens = filter(r, isMultipleOf(n: 2))
// just like before, evens is [2,4,6,8,10]
Airspeed Velocity
  • 40,491
  • 8
  • 113
  • 118
  • This looks convincing. – Mihai Damian Jan 08 '15 at 13:44
  • This currying syntax has been removed in Swift 3. See https://github.com/apple/swift-evolution/blob/master/proposals/0002-remove-currying.md and https://stackoverflow.com/questions/34159260/currying-in-swift-new-declaration-syntax-in-future. Also, `#` before parameter names was removed in Swift 3, see https://stackoverflow.com/questions/24382118/what-is-the-meaning-of-the-mark-in-swift-language. – idmean Mar 25 '21 at 12:25