bind

open suspend fun <B> Effect<R, B>.bind(): B(source)

Runs the Effect to finish, returning B or shift in case of R.

import arrow.core.Either
import arrow.core.continuations.Effect
import arrow.core.continuations.effect
import arrow.core.identity
import io.kotest.matchers.shouldBe

suspend fun <E, A> Either<E, A>.toEffect(): Effect<E, A> = effect {
fold({ e -> shift(e) }, ::identity)
}

suspend fun main() {
val either = Either.Left("failed")
effect<String, Int> {
val x: Int = either.toEffect().bind()
x
}.toEither() shouldBe either
}

open suspend fun <B> EagerEffect<R, B>.bind(): B(source)

Runs the EagerEffect to finish, returning B or shift in case of R, bridging eager computations into suspending.

import arrow.core.Either
import arrow.core.continuations.EagerEffect
import arrow.core.continuations.eagerEffect
import arrow.core.continuations.effect
import arrow.core.identity
import io.kotest.matchers.shouldBe

suspend fun <E, A> Either<E, A>.toEagerEffect(): EagerEffect<E, A> = eagerEffect {
fold({ e -> shift(e) }, ::identity)
}

suspend fun main() {
val either = Either.Left("failed")
effect<String, Int> {
val x: Int = either.toEagerEffect().bind()
x
}.toEither() shouldBe either
}

open suspend fun <B> Either<R, B>.bind(): B(source)

Folds Either into Effect, by returning B or a shift with R.

import arrow.core.Either
import arrow.core.continuations.effect
import io.kotest.matchers.shouldBe

suspend fun main() {
val either = Either.Right(9)
effect<String, Int> {
val x: Int = either.bind()
x
}.toEither() shouldBe either
}

open suspend fun <B> Validated<R, B>.bind(): B(source)

Folds Validated into Effect, by returning B or a shift with R.

import arrow.core.Validated
import arrow.core.continuations.effect
import io.kotest.matchers.shouldBe

suspend fun main() {
val validated = Validated.Valid(40)
effect<String, Int> {
val x: Int = validated.bind()
x
}.toValidated() shouldBe validated
}

open suspend fun <B> Result<B>.bind(transform: (Throwable) -> R): B(source)

Folds Result into Effect, by returning B or a transforming Throwable into R and shifting the result.

import arrow.core.continuations.effect
import arrow.core.identity
import io.kotest.matchers.shouldBe

private val default = "failed"
suspend fun main() {
val result = Result.success(1)
effect<String, Int> {
val x: Int = result.bind { _: Throwable -> default }
x
}.fold({ default }, ::identity) shouldBe result.getOrElse { default }
}

open suspend fun <B> Option<B>.bind(shift: () -> R): B(source)

Folds Option into Effect, by returning B or a transforming None into R and shifting the result.

import arrow.core.None
import arrow.core.Option
import arrow.core.continuations.effect
import arrow.core.getOrElse
import arrow.core.identity
import io.kotest.matchers.shouldBe

private val default = "failed"
suspend fun main() {
val option: Option<Int> = None
effect<String, Int> {
val x: Int = option.bind { default }
x
}.fold({ default }, ::identity) shouldBe option.getOrElse { default }
}