1

According to this SO post currying in Swift with an arbitrary number of parameters isn't possible. I'm trying to understand why. Consider this code, which in my head seems like it should work:

func addArray (numbers: [Int]) -> ((Int...) -> Any) {
    return { (nums: Int...) in 
        (nums.count > 0) ? addArray(numbers+nums) : numbers.reduce(0, combine: +)  }
}

func add (numbers: Int...) -> ((Int...) -> Any) {
    return addArray(numbers)
}

First Test:

println("sum = \(   add(11)()   )")
// => sum = 11

so far so good...

Second Test:

println("sum = \(   add(11)(12)   )")
// => sum = (Function)

excellent, now can we call that function?

Third test

println("sum = \(   add(11)(12)()   )")
// => <stdin>:19:21: error: invalid use of '()' to call a value of 
// => non-function type 'Any'
// =>     println("sum = \( add(11)(12)() )")
// =>     ^ ~~

... Huh? Didn't you just say that add(11)(12) was a function?

Now it's a non-function type 'Any' ?!1!1 wtf?

Note that I was expecting the result to be sum = 23

Community
  • 1
  • 1
Gil Birman
  • 35,242
  • 14
  • 75
  • 119

1 Answers1

2

The problem is with the return type of Any (which is the return type of the function returned by add). When you print the value of add(11)(12) you can see – due to polymorphism – that this time it returned a function type, but as far as the compiler is concerned the type of the return value is still Any (and some other time it might return another type for those parameters), which cannot be called.

If you are certain that it will return a function, you can cast it:

print("sum = \( (add(11)(12) as! ((Int...) -> Any))() )")
// => sum = 23

Note that you have the same problem of type if you try to use the Int value:

var sum = (add(11)(12) as! ((Int...) -> Any))()
sum += 1 // Error, because `sum` is `Any`

So even there you would have to do:

var sum = (add(11)(12) as! ((Int...) -> Any))() as! Int
Arkku
  • 41,011
  • 10
  • 62
  • 84