6

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.

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
lee
  • 7,955
  • 8
  • 44
  • 60

1 Answers1

10

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.

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • It's worked. But still got confused that why operator `+` can casts to function `((Int, Int) -> Int)`. Could you explain at this point? – lee Sep 11 '17 at 12:25
  • 2
    @lee: As I said, there are many overloaded + operators, they differ in the types of the parameters, e.g. `(Int, Int) -> Int` and `(Double, Double) -> Double` and many more. With `as ...` you tell the compiler which one to choose to resolve the ambiguity. – Martin R Sep 11 '17 at 12:27
  • ooh, got it. Thanks so much for your help. – lee Sep 11 '17 at 12:29