Promise

When made, a Promise is empty. That is, 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.

Constructing a Promise

A promise can easily be made by calling uncancellable. 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<Nothing, Promise<IOPartialOf<Nothing>, Int>> =
  Promise.uncancellable<IOPartialOf<Nothing>, 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 unsafeUncancellable function.

import arrow.fx.*
import arrow.fx.extensions.io.async.async

fun main(args: Array<String>) {
//sampleStart
val unsafePromise: Promise<IOPartialOf<Nothing>, Int> = Promise.unsafeUncancellable(IO.async())
//sampleEnd
println(unsafePromise)
}

Get

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.uncancellable<IOPartialOf<Nothing>, 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.uncancellable<IOPartialOf<Nothing>, Int>(IO.async()).flatMap { p ->
  p.complete(1).flatMap {
    p.get()
  }
}.unsafeRunSync()
//sampleEnd
println(result)
}

Complete

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.uncancellable<IOPartialOf<Nothing>, 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.uncancellable<IOPartialOf<Nothing>, Int>(IO.async()).flatMap { p ->
  p.complete(1).flatMap {
    p.complete(2)
  }
}
  .attempt()
  .unsafeRunSync()
//sampleEnd
println(result)
}

Error

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.uncancellable<IOPartialOf<Nothing>, 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.uncancellable<IOPartialOf<Nothing>, Int>(IO.async()).flatMap { p ->
  p.complete(1).flatMap {
    p.error(RuntimeException("Break promise"))
  }
}
  .attempt()
  .unsafeRunSync()
//sampleEnd
println(result)
}

Do you like Arrow?

Arrow Org
<