How the FlatMap API contract is compressed. Optional input for Non Optional result?

This is a flatMap contract in Swift 3.0.2

public struct Array<Element> : RandomAccessCollection, MutableCollection {
    public func flatMap<ElementOfResult>(_ transform: (Element) throws -> ElementOfResult?) rethrows -> [ElementOfResult]
}

If I take an array from [String?]flatMap returns [String]

let albums = ["Fearless", nil, "Speak Now", nil, "Red"]
let result = albums.flatMap { $0 }
type(of: result) 
// Array<String>.Type

It ElementOfResultbecomes here String, why not String?? How can a generic type system cut an optional part from an expression?

+2
source share
1 answer

{ $0 }, , ElementOfResult? ( ) Element ( ). Element - String?, ElementOfResult? == String?. , ElementOfResult String.

flatMap(_:) [String].

ElementOfResult? ElementOfResult , . .


, , , , (. ). :

Swift , [ ]. , , : Swift , , , Haskell OCaml, , , .

, , , map(_:) flatMap(_:) ( ), .

, :

// error: Unable to infer complex closure return type; add explicit type to disambiguate.
let result = albums.flatMap {
    print($0 as Any)
    return $0
}

:

// explicitly annotate [ElementOfResult] to be [String] – thus ElementOfResult == String.
let result: [String] = albums.flatMap {
    print($0 as Any)
    return $0
}

// explicitly annotate ElementOfResult? to be String? – thus ElementOfResult == String.
let result = albums.flatMap { element -> String? in
    print(element as Any)
    return element
}
+4

All Articles