Skip to content

Instantly share code, notes, and snippets.

@fluidsonic
Last active January 30, 2017 20:58
Show Gist options
  • Save fluidsonic/72b65316106baffc3735799ea8cc8b11 to your computer and use it in GitHub Desktop.
Save fluidsonic/72b65316106baffc3735799ea8cc8b11 to your computer and use it in GitHub Desktop.
Fully unwraps nested Optionals hidden behind "Any"
protocol _TypeerasedOptional {
var typeerasedSelf: Any? { get }
}
extension Optional: _TypeerasedOptional {
var typeerasedSelf: Any? {
guard let value = self else {
return nil
}
return value
}
}
func flatOptional(_ value: Any) -> Any? {
guard let optional = value as? _TypeerasedOptional else {
return value
}
return optional.typeerasedSelf.map(flatOptional)
}
func flatOptional(_ value: Any?) -> Any? {
return value.flatMap(flatOptional)
}
func flatOptional<Value>(_ value: Any) -> Value? {
guard let optional = value as? _TypeerasedOptional else {
return value as? Value
}
return optional.typeerasedSelf.flatMap(flatOptional)
}
func flatOptional<Value>(_ value: Any?) -> Value? {
return value.flatMap(flatOptional)
}
let wrapped = Optional(Optional(Optional(Optional(Optional(Optional(2)))))) as Any
// 'wrapped' is of type 'Any' holding an 'Optional<Optional<Optional<Optional<Optional<Optional<Int>>>>>>' of value '2'
print(wrapped) // prints 'Optional(Optional(Optional(Optional(Optional(Optional(2))))))'
if let unwrapped = flatOptional(wrapped) {
// 'unwrapped' is of type 'Any' holding an 'Int' of value '2'
print(unwrapped) // prints '2'
}
if let unwrapped: Int = flatOptional(wrapped) {
// 'unwrapped' is of type 'Int'
print(unwrapped) // prints '2'
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment