Yep, it looks like Optional.flatmap() is what I need. Thanks! -Kenny
> On Jan 11, 2018, at 6:55 PM, Hooman Mehr <hoo...@mac.com> wrote: > > Hi, > > Two points: > > 1) What you want to do is a common operation in functional programming called > flatMap. Optional type already supports it. To get “x != nil ? f(x) : nil” > you say: > > x.flatMap(f) > > 2) You don’t need multiple versions, because there is a subtype-supertype > relationship between functions: You need to specify the most general > signature in your single function. The most general form of the function is: > > (XType) throws -> RetType? > > To handle throwing case, you will need to define the return type of your own > function as: > > fnil<...> (...) rethrows -> RetType? > > Then it will accept any of the following signatures and it just works: > > func f0(_ x: XType) -> RetType > func f1(_ x: XType) -> RetType? > func f2(_ x: XType?) -> RetType > func f3(_ x: XType?) -> RetType? > func f0t(_ x: XType) throws -> RetType > func f1t(_ x: XType) throws -> RetType? > func f2t(_ x: XType?) throws -> RetType > func f3t(_ x: XType?) throws -> RetType? > > Hope this helps, > Hooman > >> On Jan 11, 2018, at 5:55 PM, Kenny Leung via swift-users >> <swift-users@swift.org <mailto:swift-users@swift.org>> wrote: >> >> Hi All. >> >> I’m trying to write a utility method that is kind of the opposite of “x ?? >> y”, which means “x != nil ? x : y”. I want “x != nil ? f(x) : nil” This is >> not difficult to write, but if you have "f(x)->z" and "g(x)->z?", I seem to >> need two versions of the function in order to handle it. Is there any way to >> do this with only one function? >> >> public func fnil<XType,RetType> ( >> _ x:XType?, >> _ f:(XType)->RetType >> ) >> -> RetType? >> { >> if let x = x { >> return f(x) >> } else { >> return nil >> } >> } >> >> public func fnil<XType,RetType> ( >> _ x:XType?, >> _ g:(XType)->RetType? >> ) >> -> RetType? >> { >> if let x = x { >> return g(x) >> } else { >> return nil >> } >> } >> >> private func f(_ x:Int) -> Int { >> return x >> } >> >> private func g(_ x:Int) -> Int? { >> if x == 5 { >> return nil >> } else { >> return x >> } >> } >> >> func testFnil() { >> XCTAssertNil(fnil(nil, {f($0)})) >> XCTAssertEqual(7, fnil(7,{f($0)})) >> >> XCTAssertNil(fnil(nil, {g($0)})) >> XCTAssertEqual(7, fnil(7, {g($0)})) >> XCTAssertNil(fnil(5, {g($0)})) >> } >> >> Thanks! >> >> -Kenny >> >> _______________________________________________ >> swift-users mailing list >> swift-users@swift.org <mailto: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