Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Promise #1133

Merged
merged 20 commits into from Nov 20, 2018
Merged

Promise #1133

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions modules/docs/arrow-docs/docs/_data/menu.yml
Expand Up @@ -253,6 +253,9 @@ options:
- title: Effect
url: /docs/effects/effect/

- title: Promise
url: /docs/effects/promise/

- title: Ref
url: /docs/effects/ref/

Expand Down
4 changes: 4 additions & 0 deletions modules/docs/arrow-docs/docs/docs/datatypes/intro/README.md
Expand Up @@ -145,6 +145,10 @@ They are more general than the other datatypes as they combine the abstractions

- [`Observable`]({{ '/docs/integrations/rx2/' | relative_url }})

- [`Promise`]({{ '/docs/effects/promise/' | relative_url }})

- [`Ref`]({{ '/docs/effects/ref/' | relative_url }})

#### Free

[Free]({{ '/docs/patterns/free_algebras/' | relative_url }}) is a general abstraction to represent [Domain Specific Languages]({{ '/docs/patterns/free_algebras/' | relative_url }}) that can be interpreted using Effects.
Expand Down
168 changes: 168 additions & 0 deletions modules/docs/arrow-docs/docs/docs/effects/promise/README.MD
@@ -0,0 +1,168 @@
---
layout: docs
title: Promise
permalink: /docs/effects/promise/
---

## Promise

{:.intermediate}
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`.

## Constructing a Promise

A promise can easily be made by calling `cancellable`.
Since the allocation of mutable state is not referentially transparent this side-effect is contained within `F`.

{: data-executable='true'}
```kotlin:ank
import arrow.effects.*
import arrow.effects.instances.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 `Ref` instance you can use the `unsafe` function.

{: data-executable='true'}
```kotlin:ank
import arrow.effects.*
import arrow.effects.instances.io.async.async

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

### Get

Get the promised value, suspending the fiber running the action until the result is available.

{: data-executable='true'}
```kotlin:ank
import arrow.effects.*
import arrow.effects.instances.io.async.async
import arrow.effects.instances.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
}
```

{: data-executable='true'}
```kotlin:ank
import arrow.effects.*
import arrow.effects.instances.io.async.async
import arrow.effects.instances.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)
}
```

### Complete

Fulfills the promise with a value. A promise cannot be fulfilled twice, so doing so results in an error.

{: data-executable='true'}
```kotlin:ank
import arrow.effects.*
import arrow.effects.instances.io.async.async
import arrow.effects.instances.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)
}
```

{: data-executable='true'}
```kotlin:ank
import arrow.effects.*
import arrow.effects.instances.io.async.async
import arrow.effects.instances.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)
}
```

### Error

Breaks the promise with an exception. A promise cannot be broken twice, so doing so will result in an error.

{: data-executable='true'}
```kotlin:ank
import arrow.effects.*
import arrow.effects.instances.io.async.async
import arrow.effects.instances.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)
}
```

{: data-executable='true'}
```kotlin:ank
import arrow.effects.*
import arrow.effects.instances.io.async.async
import arrow.effects.instances.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)
}
```