As an exercise in Swift, I am trying to write an extension method that will unwrap arbitrarily deeply nested optionals. This has little practical use and is simply an exploration of Swift's type system.
Examples of arbitrarily deeply nested optionals are Optional<Optional<Optional<Int>>>
and Optional<Optional<Optional<Optional<Int>>>>
.
The only way I've discovered to do this is to use type erasure:
protocol TypeErasedOptional {
func deeplyUnwrap() -> Any?
}
extension Optional: TypeErasedOptional {
func deeplyUnwrap() -> Any? {
switch self {
case .none: return nil
case .some(let wrapped as TypeErasedOptional): return wrapped.deeplyUnwrap()
case .some(let wrapped): return wrapped
}
}
func unwrap<T>(_ type: T.Type = T.self) -> T? {
switch deeplyUnwrap() {
case .none: return nil
case .some(let wrapped as T): return wrapped
default: return nil
}
}
}
This works well. We can unwrap a deeply nested optional, but unfortunately we have to restate the Wrapped
type:
let x = Optional<Optional<Optional<Int>>>(3)
let y = x.unwrap(Int.self)
I can't think of any way to do this without type erasure. And once you use type erasure, you must restate the type to get it back. I don't want this. Can someone more versed in Swift let me know either that this cannot be done or whether there is another way?