[swift-users] Generics question - can you handle both optional and non-optional args with the same function?
Kenny Leung
kenny_leung at pobox.com
Thu Jan 11 21:17:56 CST 2018
Yep, it looks like Optional.flatmap() is what I need. Thanks!
-Kenny
> On Jan 11, 2018, at 6:55 PM, Hooman Mehr <hooman at 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 at swift.org <mailto:swift-users at 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 at swift.org <mailto:swift-users at swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-users
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20180111/13c0dc0e/attachment.html>
More information about the swift-users
mailing list