Skip to content

Commit

Permalink
Fix typos reorg resource computation block (#2671)
Browse files Browse the repository at this point in the history
Co-authored-by: Simon Vergauwen <[email protected]>
  • Loading branch information
i-walker and nomisRev authored Mar 1, 2022
1 parent d381b57 commit 1d05f9d
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 55 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,10 @@ import kotlin.coroutines.resume
* Let's write a small program to read a file from disk, and instead of having the program work exception based we want to
* turn it into a polymorphic type-safe program.
*
* We'll start by defining a small function that accepts a `String`, and does some simply validation to check that the path
* We'll start by defining a small function that accepts a [String], and does some simply validation to check that the path
* is not empty. If the path is empty, we want to program to result in `EmptyPath`. So we're immediately going to see how
* we can raise an error of any arbitrary type `R` by using the function `shift`. The name `shift` comes shifting (or
* changing, especially unexpectedly), away from the computation and finishing the `Continuation` with `R`.
* we can raise an error of any arbitrary type [R] by using the function `shift`. The name `shift` comes shifting (or
* changing, especially unexpectedly), away from the computation and finishing the `Continuation` with [R].
*
* <!--- INCLUDE
* import arrow.core.continuations.Effect
Expand All @@ -65,8 +65,8 @@ import kotlin.coroutines.resume
* }
* ```
*
* Here we see how we can define an `Effect<R, A>` which has `EmptyPath` for the shift type `R`, and `Unit` for the success
* type `A`.
* Here we see how we can define an `Effect<R, A>` which has `EmptyPath` for the shift type [R], and `Unit` for the success
* type [A].
*
* Patterns like validating a [Boolean] is very common, and the [Effect] DSL offers utility functions like [kotlin.require]
* and [kotlin.requireNotNull]. They're named [EffectScope.ensure] and [ensureNotNull] to avoid conflicts with the `kotlin` namespace.
Expand Down Expand Up @@ -110,7 +110,7 @@ import kotlin.coroutines.resume
* }
* ```
*
* We can finish our function, but we need to refactor our return value from `Unit` to `Content` and our error type from `EmptyPath` to `FileError`.
* We can finish our function, but we need to refactor the return type from `Unit` to `Content` and the error type from `EmptyPath` to `FileError`.
*
* ```kotlin
* fun readFile(path: String?): Effect<FileError, Content> = effect {
Expand Down Expand Up @@ -149,7 +149,7 @@ import kotlin.coroutines.resume
* ```
* <!--- KNIT example-effect-guide-02.kt -->
*
* The functions above our available out of the box, but it's easy to define your own extension functions in terms
* The functions above are available out of the box, but it's easy to define your own extension functions in terms
* of `fold`. Implementing the `toEither()` operator is as simple as:
*
* <!--- INCLUDE
Expand Down Expand Up @@ -186,11 +186,11 @@ import kotlin.coroutines.resume
*
* ## Handling errors
*
* Handling errors of type `R` is the same as handling errors for any other data type in Arrow.
* Handling errors of type [R] is the same as handling errors for any other data type in Arrow.
* `Effect<R, A>` offers `handleError`, `handleErrorWith`, `redeem`, `redeemWith` and `attempt`.
*
* As you can see in the examples below it is possible to resolve errors of `R` or `Throwable` in `Effect<R, A>` in a generic manner.
* There is no need to run `Effect<R, A>` into `Either<R, A>` before you can access `R`,
* As you can see in the examples below it is possible to resolve errors of [R] or `Throwable` in `Effect<R, A>` in a generic manner.
* There is no need to run `Effect<R, A>` into `Either<R, A>` before you can access [R],
* you can simply call the same functions on `Effect<R, A>` as you would on `Either<R, A>` directly.
*
* <!--- INCLUDE
Expand Down Expand Up @@ -234,7 +234,7 @@ import kotlin.coroutines.resume
*
* ## Structured Concurrency
*
* `Effect<R, A>` relies on `kotlin.cancellation.CancellationException` to `shift` error values of type `R` inside the `Continuation` since it effectively cancels/short-circuits it.
* `Effect<R, A>` relies on `kotlin.cancellation.CancellationException` to `shift` error values of type [R] inside the `Continuation` since it effectively cancels/short-circuits it.
* For this reason `shift` adheres to the same rules as [`Structured Concurrency`](https://kotlinlang.org/docs/coroutines-basics.html#structured-concurrency)
*
* Let's overview below how `shift` behaves with the different concurrency builders from Arrow Fx & KotlinX Coroutines.
Expand Down
8 changes: 4 additions & 4 deletions arrow-libs/fx/arrow-fx-coroutines/api/arrow-fx-coroutines.api
Original file line number Diff line number Diff line change
Expand Up @@ -490,11 +490,11 @@ public final class arrow/fx/coroutines/Use {
public final synthetic fun unbox-impl ()Lkotlin/jvm/functions/Function1;
}

public abstract interface class arrow/fx/coroutines/computations/ResourceEffect {
public abstract fun bind (Larrow/fx/coroutines/Resource;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public final class arrow/fx/coroutines/continuations/ResourceKt {
public static final fun resource (Lkotlin/jvm/functions/Function2;)Larrow/fx/coroutines/Resource;
}

public final class arrow/fx/coroutines/computations/ResourceKt {
public static final fun resource (Lkotlin/jvm/functions/Function2;)Larrow/fx/coroutines/Resource;
public abstract interface class arrow/fx/coroutines/continuations/ResourceScope {
public abstract fun bind (Larrow/fx/coroutines/Resource;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
}

Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import arrow.core.identity
import arrow.core.invalidNel
import arrow.core.traverseValidated
import arrow.core.valid
import arrow.fx.coroutines.computations.ResourceEffect
import arrow.fx.coroutines.continuations.ResourceScope
import kotlin.coroutines.CoroutineContext
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.Dispatchers
Expand Down Expand Up @@ -171,13 +171,13 @@ public sealed class Resource<out A> {
* //sampleEnd
* }
* ```
* <!--- KNIT example-resource-04.kt -->
* <!--- KNIT example-resource-04.kt -->
*/
@Suppress("UNCHECKED_CAST")
public tailrec suspend infix fun <B> use(f: suspend (A) -> B): B =
when (this) {
is Dsl -> {
val effect = ResEffectImpl()
val effect = ResourceScopeImpl()
val b = try {
val a = dsl(effect)
f(a)
Expand All @@ -203,14 +203,14 @@ public sealed class Resource<out A> {
}

public fun <B> map(f: suspend (A) -> B): Resource<B> =
arrow.fx.coroutines.computations.resource { f(bind()) }
arrow.fx.coroutines.continuations.resource { f(bind()) }

/** Useful for setting up/configuring an acquired resource */
public fun <B> tap(f: suspend (A) -> Unit): Resource<A> =
arrow.fx.coroutines.computations.resource { bind().also { f(it) } }
arrow.fx.coroutines.continuations.resource { bind().also { f(it) } }

public fun <B> ap(ff: Resource<(A) -> B>): Resource<B> =
arrow.fx.coroutines.computations.resource {
arrow.fx.coroutines.continuations.resource {
val a = bind()
ff.bind()(a)
}
Expand Down Expand Up @@ -252,17 +252,17 @@ public sealed class Resource<out A> {
* //sampleEnd
* }
* ```
* <!--- KNIT example-resource-05.kt -->
* <!--- KNIT example-resource-05.kt -->
*
* @see zip to combine independent resources together
* @see parZip for combining independent resources in parallel
*/
public fun <B> flatMap(f: (A) -> Resource<B>): Resource<B> = arrow.fx.coroutines.computations.resource {
public fun <B> flatMap(f: (A) -> Resource<B>): Resource<B> = arrow.fx.coroutines.continuations.resource {
f(bind()).bind()
}

public inline fun <B, C> zip(other: Resource<B>, crossinline combine: (A, B) -> C): Resource<C> =
arrow.fx.coroutines.computations.resource {
arrow.fx.coroutines.continuations.resource {
combine(bind(), other.bind())
}

Expand Down Expand Up @@ -314,7 +314,7 @@ public sealed class Resource<out A> {
* }
* //sampleEnd
* ```
* <!--- KNIT example-resource-06.kt -->
* <!--- KNIT example-resource-06.kt -->
*
* @see parZip if you want to combine independent resources in parallel
* @see flatMap to combine resources that rely on each-other.
Expand All @@ -324,7 +324,7 @@ public sealed class Resource<out A> {
c: Resource<C>,
crossinline map: (A, B, C) -> D
): Resource<D> =
arrow.fx.coroutines.computations.resource {
arrow.fx.coroutines.continuations.resource {
map(bind(), b.bind(), c.bind())
}

Expand All @@ -334,7 +334,7 @@ public sealed class Resource<out A> {
d: Resource<D>,
crossinline map: (A, B, C, D) -> E
): Resource<E> =
arrow.fx.coroutines.computations.resource {
arrow.fx.coroutines.continuations.resource {
map(bind(), b.bind(), c.bind(), d.bind())
}

Expand All @@ -345,7 +345,7 @@ public sealed class Resource<out A> {
e: Resource<E>,
crossinline map: (A, B, C, D, E) -> G
): Resource<G> =
arrow.fx.coroutines.computations.resource {
arrow.fx.coroutines.continuations.resource {
map(bind(), b.bind(), c.bind(), d.bind(), e.bind())
}

Expand All @@ -357,7 +357,7 @@ public sealed class Resource<out A> {
f: Resource<F>,
crossinline map: (A, B, C, D, E, F) -> G
): Resource<G> =
arrow.fx.coroutines.computations.resource {
arrow.fx.coroutines.continuations.resource {
map(bind(), b.bind(), c.bind(), d.bind(), e.bind(), f.bind())
}

Expand All @@ -370,7 +370,7 @@ public sealed class Resource<out A> {
g: Resource<G>,
crossinline map: (A, B, C, D, E, F, G) -> H
): Resource<H> =
arrow.fx.coroutines.computations.resource {
arrow.fx.coroutines.continuations.resource {
map(bind(), b.bind(), c.bind(), d.bind(), e.bind(), f.bind(), g.bind())
}

Expand All @@ -384,7 +384,7 @@ public sealed class Resource<out A> {
h: Resource<H>,
crossinline map: (A, B, C, D, E, F, G, H) -> I
): Resource<I> =
arrow.fx.coroutines.computations.resource {
arrow.fx.coroutines.continuations.resource {
map(bind(), b.bind(), c.bind(), d.bind(), e.bind(), f.bind(), g.bind(), h.bind())
}

Expand All @@ -399,7 +399,7 @@ public sealed class Resource<out A> {
i: Resource<I>,
crossinline map: (A, B, C, D, E, F, G, H, I) -> J
): Resource<J> =
arrow.fx.coroutines.computations.resource {
arrow.fx.coroutines.continuations.resource {
map(bind(), b.bind(), c.bind(), d.bind(), e.bind(), f.bind(), g.bind(), h.bind(), i.bind())
}

Expand All @@ -415,7 +415,7 @@ public sealed class Resource<out A> {
j: Resource<J>,
crossinline map: (A, B, C, D, E, F, G, H, I, J) -> K
): Resource<K> =
arrow.fx.coroutines.computations.resource {
arrow.fx.coroutines.continuations.resource {
map(bind(), b.bind(), c.bind(), d.bind(), e.bind(), f.bind(), g.bind(), h.bind(), i.bind(), j.bind())
}

Expand Down Expand Up @@ -465,22 +465,22 @@ public sealed class Resource<out A> {
* }
* //sampleEnd
* ```
* <!--- KNIT example-resource-07.kt -->
* <!--- KNIT example-resource-07.kt -->
*/
public fun <B, C> parZip(
ctx: CoroutineContext = Dispatchers.Default,
fb: Resource<B>,
f: suspend (A, B) -> C
): Resource<C> =
arrow.fx.coroutines.computations.resource {
arrow.fx.coroutines.continuations.resource {
parZip(ctx, { this@Resource.bind() }, { fb.bind() }) { a, b -> f(a, b) }
}

@Deprecated(
"Bind is being deprecated. Use resource DSL instead",
ReplaceWith(
"resource { f(source.bind()) }",
"arrow.fx.coroutines.computations.resource"
"arrow.fx.coroutines.continuations.resource"
)
)
public class Bind<A, B>(public val source: Resource<A>, public val f: (A) -> Resource<B>) : Resource<B>()
Expand All @@ -494,20 +494,20 @@ public sealed class Resource<out A> {
"Defer is being deprecated. Use resource DSL instead",
ReplaceWith(
"resource { resource.invoke().bind() }",
"arrow.fx.coroutines.computations.resource"
"arrow.fx.coroutines.continuations.resource"
)
)
public class Defer<A>(public val resource: suspend () -> Resource<A>) : Resource<A>()

internal data class Dsl<A>(public val dsl: suspend ResourceEffect.() -> A) : Resource<A>()
internal data class Dsl<A>(public val dsl: suspend ResourceScope.() -> A) : Resource<A>()

public companion object {

@PublishedApi
internal val unit: Resource<Unit> = just(Unit)

/**
* Construct a [Resource] from a allocating function [acquire] and a release function [release].
* Construct a [Resource] from an allocating function [acquire] and a release function [release].
*
* ```kotlin
* import arrow.fx.coroutines.*
Expand All @@ -524,7 +524,7 @@ public sealed class Resource<out A> {
* //sampleEnd
* }
* ```
* <!--- KNIT example-resource-08.kt -->
* <!--- KNIT example-resource-08.kt -->
*/
public operator fun <A> invoke(
acquire: suspend () -> A,
Expand All @@ -537,6 +537,13 @@ public sealed class Resource<out A> {
public fun <A> just(r: A): Resource<A> =
Resource({ r }, { _, _ -> Unit })

@Deprecated(
"defer is being deprecated. Use resource DSL instead",
ReplaceWith(
"resource { f().bind() }",
"arrow.fx.coroutines.continuations.resource"
)
)
public fun <A> defer(f: suspend () -> Resource<A>): Resource<A> =
Resource.Defer(f)
}
Expand Down Expand Up @@ -577,7 +584,7 @@ public sealed class Resource<out A> {
"Use the resource computation DSL instead",
ReplaceWith(
"resource { acquire() }",
"arrow.fx.coroutines.computations.resource"
"arrow.fx.coroutines.continuations.resource"
)
)
public inline class Use<A>(internal val acquire: suspend () -> A)
Expand All @@ -589,7 +596,7 @@ public inline class Use<A>(internal val acquire: suspend () -> A)
"Use the resource computation DSL instead",
ReplaceWith(
"resource { acquire() }",
"arrow.fx.coroutines.computations.resource"
"arrow.fx.coroutines.continuations.resource"
)
)
public fun <A> resource(acquire: suspend () -> A): Use<A> = Use(acquire)
Expand All @@ -602,7 +609,7 @@ public infix fun <A> Use<A>.release(release: suspend (A) -> Unit): Resource<A> =
* Composes a [release] action to a [Resource.use] action creating a [Resource].
*/
public infix fun <A> Resource<A>.release(release: suspend (A) -> Unit): Resource<A> =
arrow.fx.coroutines.computations.resource {
arrow.fx.coroutines.continuations.resource {
val a = bind()
Resource({ a }, { _, _ -> release(a) }).bind()
}
Expand All @@ -615,7 +622,7 @@ public infix fun <A> Use<A>.releaseCase(release: suspend (A, ExitCase) -> Unit):
* Composes a [releaseCase] action to a [Resource.use] action creating a [Resource].
*/
public infix fun <A> Resource<A>.releaseCase(release: suspend (A, ExitCase) -> Unit): Resource<A> =
arrow.fx.coroutines.computations.resource {
arrow.fx.coroutines.continuations.resource {
val a = bind()
Resource({ a }, { _, ex -> release(a, ex) }).bind()
}
Expand Down Expand Up @@ -658,7 +665,7 @@ public infix fun <A> Resource<A>.releaseCase(release: suspend (A, ExitCase) -> U
* <!--- KNIT example-resource-10.kt -->
*/
public inline fun <A, B> Iterable<A>.traverseResource(crossinline f: (A) -> Resource<B>): Resource<List<B>> =
arrow.fx.coroutines.computations.resource {
arrow.fx.coroutines.continuations.resource {
map { a ->
f(a).bind()
}
Expand Down Expand Up @@ -706,11 +713,11 @@ public inline fun <A, B> Iterable<A>.traverseResource(crossinline f: (A) -> Reso
public inline fun <A> Iterable<Resource<A>>.sequence(): Resource<List<A>> =
traverseResource(::identity)

private class ResEffectImpl : ResourceEffect {
private class ResourceScopeImpl : ResourceScope {
val finalizers: AtomicRef<List<suspend (ExitCase) -> Unit>> = AtomicRef(emptyList())
override suspend fun <A> Resource<A>.bind(): A =
when (this) {
is Resource.Dsl -> dsl.invoke(this@ResEffectImpl)
is Resource.Dsl -> dsl.invoke(this@ResourceScopeImpl)
is Resource.Allocate -> bracketCase({
val a = acquire()
val finalizer: suspend (ExitCase) -> Unit = { ex: ExitCase -> release(a, ex) }
Expand All @@ -726,12 +733,12 @@ private class ResEffectImpl : ResourceEffect {
}
})
is Resource.Bind<*, *> -> {
val dsl: suspend ResourceEffect.() -> A = {
val dsl: suspend ResourceScope.() -> A = {
val any = source.bind()
val ff = f as (Any?) -> Resource<A>
ff(any).bind()
}
dsl(this@ResEffectImpl)
dsl(this@ResourceScopeImpl)
}
is Resource.Defer -> resource().bind()
}
Expand Down
Loading

0 comments on commit 1d05f9d

Please sign in to comment.