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> 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 > https://lists.swift.org/mailman/listinfo/swift-users
_______________________________________________ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users