Skip to content

Instantly share code, notes, and snippets.

@raulraja
Created March 1, 2022 11:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save raulraja/c31ef316e6e83c548966e3bdb66259c0 to your computer and use it in GitHub Desktop.
Save raulraja/c31ef316e6e83c548966e3bdb66259c0 to your computer and use it in GitHub Desktop.
EffectScope pipe
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