Skip to content

Instantly share code, notes, and snippets.

@andelf
Last active November 21, 2018 19:55
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save andelf/9e565319b94c9aa9cbb6 to your computer and use it in GitHub Desktop.
Save andelf/9e565319b94c9aa9cbb6 to your computer and use it in GitHub Desktop.
Swift Optional Extension
protocol Index {
typealias IndexType
typealias Result
subscript (i: IndexType) -> Result { get }
}
protocol IndexMut: Index {
typealias IndexType
typealias Result
subscript (i: IndexType) -> Result { set get }
}
extension Optional {
func is_some() -> Bool {
switch self {
case .Some(_):
return true
case _:
return false
}
}
func is_none() -> Bool {
switch self {
case .None:
return true
case _:
return false
}
}
func expect(msg: StaticString) -> T {
switch self {
case .Some(let val):
return val
case _:
fatalError(msg)
}
}
@transparent func unwrap() -> T {
return self!
}
func unwrap_or(def: T) -> T {
switch self {
case .Some(let val):
return val
case _:
return def
}
}
func unwrap_or_else(f: () -> T) -> T {
switch self {
case .Some(let val):
return val
case _:
return f()
}
}
func map_or<U>(def: U, f: (T) -> U) -> U {
switch self {
case .Some(let val):
return f(val)
case _:
return def
}
}
func add<U>(optb: Optional<U>) -> Optional<U> {
if self {
return optb
} else {
return nil
}
}
func add_then<U>(f: (T) -> Optional<U>) -> Optional<U> {
if self {
return f(self!)
} else {
return nil
}
}
func or(optb: Optional<T>) -> Optional<T> {
if self {
return self
} else {
return optb
}
}
func or_else(f: () -> Optional<T>) -> Optional<T> {
if self {
return self
} else {
return f()
}
}
func filtered(f: (T) -> Bool) -> Optional<T> {
if self.map_or(false, f) {
return self
} else {
return nil
}
}
func while_some(f: (T) -> Optional<T>) {
var val = self
while val {
val = val.map(f).unwrap_or(nil)
}
}
}
extension Optional: Sequence, Generator {
public func generate() -> T? {
return self
}
public func next() -> T? {
return self
}
}
@pr1001
Copy link

pr1001 commented Feb 2, 2016

I think you should be able to simply for methods by combining the value and function methods with @autoclosure, e.g or and or_else could become:

func or(@autoclosure f: () -> Optional<T>) -> Optional<T> {
    if self {
        return self
    } else {
        return f()
    }
}

Then you could write:

myOptional or 42

or

myOptional or {
  39 + 3
}

This is untested...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment