Why is count ambiguous here?

 let x = [1: ["a", "b", "c", "d"],
      2: ["e", "f", "g"],
      3: ["h", "i"]]
 
 let total = x.reduce(0) {&$0 += $1.value.count}

Wow, that's terse. Try breaking that expression up, my guess is this is actually not the right error, but the type checker is getting confused.

The error message is misleading. The closure must return the accumulated value:

let total = x.reduce(0) { $0 + $1.value.count }

Or perhaps you meant to use reduce(into:_:) ? Here the accumulated value is passed as an inout argument to the closure and can be updated:

let total1 = x.reduce(into: 0) { $0 += $1.value.count }
6 Likes

This is simply a diagnostics engine bug. Believe it or not, typing something on the next line fixes the error message:

_ = x.reduce(0) { f, s in
  
  &f += s.value.count // Ambiguous reference to member 'count'
}

_ = x.reduce(0) { f, s in
  
  &f += s.value.count // Cannot pass immutable value as inout argument: 'f' is a 'let' constant
  "ffff"
}

I'm going to file this if you don't mind. UDP SR-7543

3 Likes

Thanks @Martin. That's what I meant to do.