try? shouldn't work on non-method-call


(Braeden Profile) #1

I do think that the status quo is good for try? precedence and such, but how about the original problem? The code was hard to work with because it used a double nested Optional. If you really don’t care about the reason that code failed, then a single optional should be returned. There’s this:

if let rawA = try? couldFailButWillNot(),
   let a = rawA as? Int
{
    print(a)
}

…but it seems overly verbose. I think it would be easier if the standard library included flatMap()’s companion, flattened() Optional<Optional<T>>, much like the existing flatMap() and flatten() of Array<Array<T>>. Unfortunately, this isn’t really possible:

extension Optional where Wrapped == Optional<T>
{
    func flattened() -> Wrapped
    {
        if let wrapped = self
            { return wrapped }
        else
            { return nil }
    }
}

if let a = (try? couldFailButWillNot() as? Int).flattened() {
    print(a)
}

…as the compiler complains that “T” is unresolved and that you can’t constrain an extension with a generic type—or any non-protocol type, for that matter. A free flattened() function would work, but wouldn’t be very clean or intuitive. flatMap works for now, but isn’t great:

if let a = (try? couldFailButWillNot() as? Int)?.flatMap({$0}) {
    print(a)
}

I guess that feature will have to wait until Swift 4.