The object we were using flatMap on used to be optional. The fix was to use a map instead since it was no longer needed to be flatMapped. I agree that this would be a mis-use of flatMap but the inference behaviour here is still unexpected.
If the compiler doesn't support multi-statement closure type inference it would be nice for it to warn or error out in cases like this to enforce type, or it can also be handled by a linter/static analysis. - Santiago On Sat, Oct 21, 2017 at 12:39 PM Martin R <martinr...@gmail.com> wrote: > Compare https://bugs.swift.org/browse/SR-1570 : Swift can infer the > return type from single-statement closures, but not from multi-statement > closures. Therefore in > > let result = strArr.flatMap { x in > return x > } > > the closure type is inferred as (String)-> String, and therefore the > flatMap call matches exactly the > > func flatMap<SegmentOfResult>(_ transform: (Self.Element) throws -> > SegmentOfResult) rethrows -> [SegmentOfResult.Element] > where SegmentOfResult : Sequence > > Sequence method, with Self.Element == String and SegmentOfResult == > String, and flatMap returns [SegmentOfResult.Element] == [Character]. > > In > > let result = strArr.flatMap { x in > print(x) > return x > } > > the closure return type is not inferred from the closure itself, because > it is a multi-statement closure. Here the compiler (apparently) chooses the > > public func flatMap(_ transform: (Element) throws -> String?) rethrows > -> [String] > > Array method, and promotes `String` to `String?`. You would get the same > result with an explicit return type in the single-statement closure: > > let result = strArr.flatMap { x -> String? in > return x > } > > But why do you use flatMap at all? If the intention is to map [String] to > [String] then map() would be the right method: > > let strArr = ["Hi", "hello"] > let result: [String] = strArr.map { x in > return x > } > print(result) // ["Hi", "hello"] > > Regards, Martin > > > > On 21. Oct 2017, at 02:50, Santiago Gil via swift-users < > swift-users@swift.org> wrote: > > > > Hi Swift users, > > > > I just ran into a bug after a Swift 4 migration where we expected > [String] and got [Character] from a flatMap since flatMap will flatten the > String since it's now a collection. While I understand why flatMap behaves > this way now that string are collections, in testing this I found some > weird behaviour... > > > > var strArr = ["Hi", "hello"] > > > > let result = strArr.flatMap { x in > > > > return x > > > > } > > > > > > The type of results ends up being [Character] in the above case. > However, adding a print statement changes things. > > > > > > var strArr = ["Hi", "hello"] > > > > let result = strArr.flatMap { x in > > > > print(x) > > > > return x > > > > } > > > > In this case, result is of type [String] > > > > This seems like a bug, or is this expected Swift behaviour? > > > > Thanks, > > > > Santiago > > > > _______________________________________________ > > swift-users mailing list > > swift-users@swift.org > > https://lists.swift.org/mailman/listinfo/swift-users > >
_______________________________________________ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users