Skip to content

Commit

Permalink
Merge branch 'main' into renovate/all
Browse files Browse the repository at this point in the history
  • Loading branch information
i-walker committed May 23, 2022
2 parents 753f400 + dfe0bae commit d489686
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 11 deletions.
7 changes: 7 additions & 0 deletions arrow-libs/core/arrow-core/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
id(libs.plugins.kotlin.multiplatform.get().pluginId)
alias(libs.plugins.arrowGradleConfig.kotlin)
Expand Down Expand Up @@ -40,3 +42,8 @@ kotlin {
}
}
}

// enables context receivers for Jvm Tests
tasks.named<KotlinCompile>("compileTestKotlinJvm") {
kotlinOptions.freeCompilerArgs += "-Xcontext-receivers"
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import kotlin.coroutines.RestrictsSuspension
* An [effect] computation interoperates with an [EagerEffect] via `bind`.
* @see Effect
*/
public interface EagerEffect<R, A> {
public interface EagerEffect<out R, out A> {

/**
* Runs the non-suspending computation by creating a [Continuation] with an [EmptyCoroutineContext],
Expand Down Expand Up @@ -91,24 +91,24 @@ public interface EagerEffect<R, A> {
* [fold] the [EagerEffect] into an [Option]. Where the shifted value [R] is mapped to [Option] by the
* provided function [orElse], and result value [A] is mapped to [Some].
*/
public fun toOption(orElse: (R) -> Option<A>): Option<A> =
public fun toOption(orElse: (R) -> Option<@UnsafeVariance A>): Option<A> =
fold(orElse, ::Some)

public fun <B> map(f: (A) -> B): EagerEffect<R, B> = flatMap { a -> eagerEffect { f(a) } }

public fun <B> flatMap(f: (A) -> EagerEffect<R, B>): EagerEffect<R, B> = eagerEffect {
public fun <B> flatMap(f: (A) -> EagerEffect<@UnsafeVariance R, B>): EagerEffect<R, B> = eagerEffect {
f(bind()).bind()
}

public fun attempt(): EagerEffect<R, Result<A>> = eagerEffect {
kotlin.runCatching { bind() }
}

public fun handleError(f: (R) -> A): EagerEffect<Nothing, A> = eagerEffect {
public fun handleError(f: (R) -> @UnsafeVariance A): EagerEffect<Nothing, A> = eagerEffect {
fold(f, ::identity)
}

public fun <R2> handleErrorWith(f: (R) -> EagerEffect<R2, A>): EagerEffect<R2, A> =
public fun <R2> handleErrorWith(f: (R) -> EagerEffect<R2, @UnsafeVariance A>): EagerEffect<R2, A> =
eagerEffect {
toEither().fold({ r -> f(r).bind() }, ::identity)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import kotlin.coroutines.RestrictsSuspension

/** Context of the [EagerEffect] DSL. */
@RestrictsSuspension
public interface EagerEffectScope<R> {
public interface EagerEffectScope<in R> {

/** Short-circuit the [EagerEffect] computation with value [R].
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -568,7 +568,7 @@ import kotlin.coroutines.resume
* ```
* <!--- KNIT example-effect-guide-13.kt -->
*/
public interface Effect<R, A> {
public interface Effect<out R, out A> {
/**
* Runs the suspending computation by creating a [Continuation], and running the `fold` function
* over the computation.
Expand Down Expand Up @@ -637,7 +637,7 @@ public interface Effect<R, A> {
* [fold] the [Effect] into an [Option]. Where the shifted value [R] is mapped to [Option] by the
* provided function [orElse], and result value [A] is mapped to [Some].
*/
public suspend fun toOption(orElse: suspend (R) -> Option<A>): Option<A> = fold(orElse, ::Some)
public suspend fun toOption(orElse: suspend (R) -> Option<@UnsafeVariance A>): Option<A> = fold(orElse, ::Some)

/**
* [fold] the [Effect] into an [A?]. Where the shifted value [R] is mapped to
Expand All @@ -654,11 +654,11 @@ public interface Effect<R, A> {
}
}

public fun handleError(recover: suspend (R) -> A): Effect<Nothing, A> = effect {
public fun handleError(recover: suspend (R) -> @UnsafeVariance A): Effect<Nothing, A> = effect {
fold(recover, ::identity)
}

public fun <R2> handleErrorWith(recover: suspend (R) -> Effect<R2, A>): Effect<R2, A> = effect {
public fun <R2> handleErrorWith(recover: suspend (R) -> Effect<R2, @UnsafeVariance A>): Effect<R2, A> = effect {
fold({ recover(it).bind() }, ::identity)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract

/** Context of the [Effect] DSL. */
public interface EffectScope<R> {
public interface EffectScope<in R> {
/**
* Short-circuit the [Effect] computation with value [R].
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package arrow.core.continuations

import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.Dispatchers

sealed interface MyError
sealed interface SubError : MyError
sealed interface OtherError : MyError {
object Actual : OtherError
}

context(EffectScope<SubError>)
suspend fun subprogram(): Unit =
println("Hello SubProgram!")

context(EffectScope<OtherError>)
suspend fun otherprogram(): Unit =
println("Hello OtherProgram!")

context(EffectScope<OtherError>)
suspend fun fail(): MyResponse =
shift(OtherError.Actual)

fun main() =
runBlocking(Dispatchers.Default) {
effect<MyError, Unit> {
subprogram()
otherprogram()
fail()
}.fold(::println) { }
// Hello SubProgram!
// Hello OtherProgram!
// OtherError$Actual@7cd62f43
}

sealed interface MyResponse
object EmptyResponse : MyResponse
data class ErrorResponse(val error: Throwable) : MyResponse
data class BodyResponse(val body: String) : MyResponse

context(EffectScope<SubError>)
suspend fun respondWithBody(): BodyResponse =
BodyResponse("Hello Program!")

context(EffectScope<OtherError>)
suspend fun attemptOrError(): MyResponse =
ErrorResponse(RuntimeException("Oh no!"))

fun respond(): Effect<MyError, MyResponse> =
effect {
when (attemptOrError()) {
is BodyResponse -> respondWithBody()
EmptyResponse -> EmptyResponse
is ErrorResponse -> fail()
}
}

0 comments on commit d489686

Please sign in to comment.