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