I try to understand the function currying tutorial but that code seem out of date. And it's still not really clear about function currying.
I try with this function:
func curry<A, B, C>(_ f: @escaping (A, B) -> C) -> (A) -> (B) -> C {
return { a in { b in f(a, b)} }
}
And it runs ok with Playground (Xcode 9 beta 6)
. But the problem is I cannot use this function as the tutorial:
let add = curry(+)
let xs = 1...100
let x = xs.map(add(2))
The code above return error:
Playground execution failed:
error: FunctionsCurrying.playground:31:17: error: ambiguous use of operator '+'
let add = curry(+)
^
Please correct me and help me to clear about function currying
.
currying is the technique of translating the evaluation of a function that takes multiple arguments into evaluating a sequence of functions, each with a single argument. We have a function that takes multiple arguments.
A curried function is a function of several arguments rewritten such that it accepts the first argument and returns a function that accepts the second argument and so on. This allows functions of several arguments to have some of their initial arguments partially applied.
Currying means that the closure does not have to receive all of its arguments at once, but separately. I've found this useful metaphor around the internet: Think of currying as adding ingredients (arguments, or other spices) to a function one by one. You can drop some arguments now, and other arguments as you go.
Currying: A function returning another function that might return another function, but every returned function must take only one parameter at a time. Partial application: A function returning another function that might return another function, but each returned function can take several parameters.
That problem is not Swift 4 related, you would get the same error message in Swift 3.
There are many overloaded +
operators, therefore in
let add = curry(+)
the compiler does not know which one to choose. With an explicit type cast
let add = curry((+) as ((Int, Int) -> Int))
or an explicit type annotation
let op: (Int, Int) -> Int = (+)
let add = curry(op)
the code compiles and runs as expected.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With