intermediate
When made, a Promise
is empty. Until it is fulfilled, which can only happen once.
A Promise
guarantees (promises) A
at some point in the future within the context of F
.
A promise can easily be made by calling uncancelable
.
Since the allocation of mutable state is not referentially transparent this side-effect is contained within F
.
import arrow.fx.*
import arrow.fx.extensions.io.async.async
fun main(args: Array<String>) {
//sampleStart
val promise: IO<Promise<ForIO, Int>> =
Promise.uncancelable<ForIO, Int>(IO.async()).fix()
//sampleEnd
println(promise)
}
In case you want the side-effect to execute immediately and return the Promise
instance you can use the unsafeUncancelable
function.
import arrow.fx.*
import arrow.fx.extensions.io.async.async
fun main(args: Array<String>) {
//sampleStart
val unsafePromise: Promise<ForIO, Int> = Promise.unsafeUncancelable(IO.async())
//sampleEnd
println(unsafePromise)
}
Get the promised value, suspending the fiber running the action until the result is available.
import arrow.fx.*
import arrow.fx.extensions.io.async.async
import arrow.fx.extensions.io.monad.flatMap
fun main(args: Array<String>) {
//sampleStart
Promise.uncancelable<ForIO, Int>(IO.async()).flatMap { p ->
p.get()
} //never ends because `get` keeps waiting for p to be fulfilled.
//sampleEnd
}
import arrow.fx.*
import arrow.fx.extensions.io.async.async
import arrow.fx.extensions.io.monad.flatMap
fun main(args: Array<String>) {
//sampleStart
val result = Promise.uncancelable<ForIO, Int>(IO.async()).flatMap { p ->
p.complete(1).flatMap {
p.get()
}
}.unsafeRunSync()
//sampleEnd
println(result)
}
Fulfills the promise with a value. A promise cannot be fulfilled twice, so doing so results in an error.
import arrow.fx.*
import arrow.fx.extensions.io.async.async
import arrow.fx.extensions.io.monad.flatMap
fun main(args: Array<String>) {
//sampleStart
val result = Promise.uncancelable<ForIO, Int>(IO.async()).flatMap { p ->
p.complete(2).flatMap {
p.get()
}
}.unsafeRunSync()
//sampleEnd
println(result)
}
import arrow.fx.*
import arrow.fx.extensions.io.async.async
import arrow.fx.extensions.io.monad.flatMap
fun main(args: Array<String>) {
//sampleStart
val result = Promise.uncancelable<ForIO, Int>(IO.async()).flatMap { p ->
p.complete(1).flatMap {
p.complete(2)
}
}
.attempt()
.unsafeRunSync()
//sampleEnd
println(result)
}
Breaks the promise with an exception. A promise cannot be broken twice, so doing so will result in an error.
import arrow.fx.*
import arrow.fx.extensions.io.async.async
import arrow.fx.extensions.io.monad.flatMap
fun main(args: Array<String>) {
//sampleStart
val result = Promise.uncancelable<ForIO, Int>(IO.async()).flatMap { p ->
p.error(RuntimeException("Break promise"))
}
.attempt()
.unsafeRunSync()
//sampleEnd
println(result)
}
import arrow.fx.*
import arrow.fx.extensions.io.async.async
import arrow.fx.extensions.io.monad.flatMap
fun main(args: Array<String>) {
//sampleStart
val result = Promise.uncancelable<ForIO, Int>(IO.async()).flatMap { p ->
p.complete(1).flatMap {
p.error(RuntimeException("Break promise"))
}
}
.attempt()
.unsafeRunSync()
//sampleEnd
println(result)
}