Created
March 1, 2022 11:17
-
-
Save raulraja/c31ef316e6e83c548966e3bdb66259c0 to your computer and use it in GitHub Desktop.
EffectScope pipe
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package examples | |
import arrow.core.Either | |
import arrow.core.continuations.EffectScope | |
import arrow.core.continuations.either | |
object Request | |
object Response | |
sealed interface Error | |
object InvalidRequest : Error | |
object PersistenceError : Error | |
object NotifyError : Error | |
object ResponseError : Error | |
suspend fun EffectScope<Error>.validate(request: Request): Request = | |
request.also { println("validated") } | |
suspend fun EffectScope<Error>.persist(request: Request): Request = | |
request.also { println("persisted") } | |
suspend fun EffectScope<Error>.notify(request: Request): Request = | |
shift<Request>(NotifyError).also { println("unreachable") } | |
suspend fun <E : Error> EffectScope<E>.getResponse(request: Request): Response = | |
Response.also { println("response obtained") } | |
suspend fun program(): Either<Error, Response> = | |
either { | |
val valid = validate(Request) | |
val persisted = persist(valid) | |
val notified = notify(persisted) | |
val response = getResponse(notified) | |
response | |
} | |
// suspended let for suspend receivers in a context. | |
// this is not needed with multiple context receivers | |
// as you can define pipe to be in the context of T and EffectScope<R> | |
// using div as alternative to `|>` > is not allowed char even en backticks. | |
public suspend inline infix operator fun <T, R> T.div(block: suspend (T) -> R): R { | |
return block(this) | |
} | |
suspend fun EffectScope<Error>.programPiped(): Response = | |
Request / | |
::validate / | |
::persist / | |
::notify / | |
::getResponse | |
suspend fun main() { | |
val regular: Either<Error, Response> = program() | |
val piped: Either<Error, Response> = either { programPiped() } | |
println("regular: $regular") //regular: Either.Left(examples.NotifyError@6d5380c2) | |
println("piped: $piped") //piped: Either.Left(examples.NotifyError@6d5380c2) | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment