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

Reply via email to