We use Option
to indicate a computation can fail somehow (that is, it can have either zero results or one result), and we use lists for computations that can have many possible results (ranging from zero to arbitrarily many results). In both of these cases, one useful operation is combining all possible results from multiple computations into a single computation. The Alternative
type class captures this combination.
Alternative
is for Applicative
functors which also have a Monoid
structure.
Is a binary function which represents a choice between alternatives.
fun <A> Kind<F, A>.orElse(b: Kind<F, A>): Kind<F, A>
import arrow.core.Option
import arrow.core.extensions.option.monadCombine.monadCombine
Option.monadCombine().run {
val x: Option<Int> = Option.just(1)
val y: Option<Int> = Option.empty()
x.orElse(y)
}
// Option.Some(1)
import arrow.core.ListK
import arrow.core.extensions.listk.monadCombine.monadCombine
import arrow.core.k
ListK.monadCombine().run {
val x = listOf(1, 2).k()
val y = listOf(3, 4).k()
x.orElse(y)
}
// [1, 2, 3, 4]
It is just an infix alias over orElse
.
import arrow.core.Option
import arrow.core.extensions.option.monadCombine.monadCombine
Option.monadCombine().run {
val x: Option<Int> = Option.just(1)
val y: Option<Int> = Option.empty()
x alt y
}
// Option.Some(1)
fun <A> Kind<F, A>.some(): Kind<F, SequenceK<A>>
Repeats the current computation, lazily collecting its results into a sequence, until it fails. It is required that the computation succeeds at least once.
import arrow.core.Option
import arrow.core.extensions.option.monadCombine.monadCombine
Option.monadCombine().run {
val x = Option.just(1)
x.some().map { it.take(5).toList() }
}
// Option.Some([1, 1, 1, 1, 1])
import arrow.core.Option
import arrow.core.extensions.option.monadCombine.monadCombine
Option.monadCombine().run {
val x = Option.empty<Int>()
x.some().map { it.take(5).toList() }
}
// Option.None
fun <A> Kind<F, A>.many(): Kind<F, SequenceK<A>>
Same function as some, but it does not require the computation to succeed.
import arrow.core.Option
import arrow.core.extensions.option.monadCombine.monadCombine
Option.monadCombine().run {
val x = Option.empty<Int>()
x.many().map { it.take(5).toList() }
}
// Option.Some([])
Arrow provides AlternativeLaws
in the form of test cases for internal verifications of lawful instances and third party apps creating their own Alternative
instances.
Additionally all the instances of MonadCombine
implement the Alternative
directly since it is subtype of Alternative
.
Do you like Arrow?
✖