11

The following code compiles in Swift 3

extension Array where Element: Equatable {
    var removeDuplicate: [Element] {
        return reduce([]){ $0.0.contains($0.1) ? $0.0 : $0.0 + [$0.1] }
    }
}

but produces the error

error: contextual closure type '(_, _) -> _' expects 2 arguments, but 1 was used in closure body

in Swift 4. How to convert this code to be compiled in Swift 4?

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
Senocico Stelian
  • 1,378
  • 15
  • 23
  • 1
    The original error message was due to the spurious `(0)` in the code. But even without that error there remains a Swift 3 to 4 transition problem. I have taken the liberty to edit your question in a way that it is (hopefully) more useful to future readers. – Please check if that is OK for you. – Martin R Sep 26 '17 at 18:08
  • Btw: I noticed that you got answers for all of your questions, but never *accepted* an answer so far. If you are not aware of it: Accepting an answer is important as it both rewards posters for solving your problem and informs others that your issue is resolved. See [What should I do when someone answers my question?](https://math.stackexchange.com/help/someone-answers) and [How does accepting an answer work?](https://meta.stackexchange.com/q/5234/196432) for more information. – Martin R Oct 20 '20 at 12:02

1 Answers1

15

The closure passed to reduce takes 2 parameters, e.g. $0 and $1 in the shorthand notation:

extension Array where Element: Equatable {
    var removeDuplicate: [Element] {
        return reduce([]) { $0.contains($1) ? $0 : $0 + [$1] }
    }
}

(This compiles in both Swift 3 and 4.)

In Swift 3 you could use single parameter $0, which would the be inferred as a tuple with elements $0.0 and $0.1. This is not possible anymore in Swift 4, as a consequence of SE-0110 Distinguish between single-tuple and multiple-argument function types.

Here is another example demonstrating the change: This

let clo1: (Int, Int) -> Int = { (x, y) in x + y }
let clo2: ((Int, Int)) -> Int = { z in z.0 + z.1 }

both compiles in Swift 3 and 4, but this

let clo3: (Int, Int) -> Int = { z in z.0 + z.1 }

compiles only in Swift 3, not in Swift 4.

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382