Challenge: Flattening nested optionals

May I present this non-recursive solution which doesn't erase the type (but still works for Any?):

func funwrap<T>(_ v: T????????????????????) -> T? {
    return (v as? T?) ?? nil
}

It works for 0 through 20 levels of optionality.

Adding more than 20 gets hard on the type checker, and the following demonstration program will take 15 seconds to compile on my machine:

func funwrap<T>(_ v: T????????????????????) -> T? {
    return (v as? T?) ?? nil
}

let  v0: Int = 0
let  v1: Int? = nil
let  v2: Int?? = 2
let  v3: Int??? = nil
let  v4: Int???? = 4
let  v5: Int????? = nil
let v20: Int???????????????????? = 20

let result: [Int?] = [ funwrap(v0), funwrap(v1), funwrap(v2), funwrap(v3),
    funwrap(v4), funwrap(v5), funwrap(v20) ]

print(result)

$ time swiftc demo.swift
real 0m15.087s
user 0m14.762s
sys 0m0.270s
$ ./demo
[Optional(0), nil, Optional(2), nil, Optional(4), nil, Optional(20)]

But isn't the simplest solution to just use as? T? directly, like this:

// Here, v can have any level of optionality, although there will be a warning
// when flattening if the level is 0, 1 or 2:
let v: Int??????????????????????????????????????????????????????????? = 123
let flattenedToOneLevelOfOptionality = (v as? Int?) ?? nil

print(type(of: flattenedToOneLevelOfOptionality)) // Always prints Optional<Int>
dump(flattenedToOneLevelOfOptionality)
2 Likes