Last active
January 30, 2017 20:58
-
-
Save fluidsonic/72b65316106baffc3735799ea8cc8b11 to your computer and use it in GitHub Desktop.
Fully unwraps nested Optionals hidden behind "Any"
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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