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

Reply via email to