Skip to content

Instantly share code, notes, and snippets.

@danherrera
Last active August 23, 2020 20:41
Show Gist options
  • Save danherrera/514090d2f09e4c4a16deff3ea82f3f91 to your computer and use it in GitHub Desktop.
Save danherrera/514090d2f09e4c4a16deff3ea82f3f91 to your computer and use it in GitHub Desktop.
Handle the 4 possible cases when dealing with 2 `Option` objects.
sealed class QuaternaryCase<T> {
data class Both<T>(val a: T, val b: T) : QuaternaryCase<T>()
data class OnlyA<T>(val a: T) : QuaternaryCase<T>()
data class OnlyB<T>(val b: T) : QuaternaryCase<T>()
class None<T> : QuaternaryCase<T>()
}
fun <T, R> Option<T>.map2Case(b: Option<T>, f: (case: QuaternaryCase<T>) -> R): R {
return Ior.fromOptions(this, b)
.map { ior ->
when (ior) {
is Ior.Left -> QuaternaryCase.OnlyA(ior.value)
is Ior.Right -> QuaternaryCase.OnlyB(ior.value)
is Ior.Both -> QuaternaryCase.Both(ior.leftValue, ior.rightValue)
}
}
.getOrElse { QuaternaryCase.None() }
.let(f)
}
fun exampleUsage(a: Option<Int>, b: Option<Int>) {
val value = a.map2Case(b) {
when (it) {
is QuaternaryCase.Both -> it.a + it.b
is QuaternaryCase.OnlyA -> it.a
is QuaternaryCase.OnlyB -> it.b
is QuaternaryCase.None -> -1
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment