inline-option/Option.kt
2020-10-02 16:13:26 +02:00

47 lines
1.2 KiB
Kotlin

@Suppress("NON_PUBLIC_PRIMARY_CONSTRUCTOR_OF_INLINE_CLASS", "UNCHECKED_CAST")
inline class Option<A> private constructor(val value: Any?) {
inline fun <R> map(op: (A) -> R): Option<R> =
if (this.value === EmptyOptionValue) {
this as Option<R>
} else {
Option.just(op(this.value as A))
}
inline fun filter(op: (A) -> Boolean): Option<A> =
if (this.value === EmptyOptionValue || !op(this.value as A)) {
none()
} else {
this
}
inline fun <R> fold(ifPresent: (A) -> R, ifEmpty: () -> R): R =
if (this.value === EmptyOptionValue) {
ifEmpty()
} else {
ifPresent(this.value as A)
}
fun getOrNull(): A? =
if (this.value === EmptyOptionValue) {
null
} else {
this.value as A
}
companion object {
private val EMPTY = Option<Any>(EmptyOptionValue)
fun <A> none() = EMPTY as Option<A>
fun <A> just(value: A) = Option<A>(value)
}
}
/**
* Marker for empty options.
* This is necessary to allow nullable types in the option.
* TODO: Somehow don’t expose this.
*/
object EmptyOptionValue