thanh
09/12/2022, 9:25 AMmapLeft in the new EffectScope?
context(EffectScope<Throwable>)
fun count(): Int = TODO()
sealed interface DomainError
context(EffectScope<DomainError>)
fun logic(): Int {
// I want to map Throwable to DomainError here
return count()
}simon.vergauwen
09/12/2022, 9:27 AMeffect and then call fold. Or turn it into an Either and call mapLeft and rebind.
effect<Throwable, Int> {
count()
}.fold({ shift(transform(it)) }, { it })simon.vergauwen
09/12/2022, 9:29 AMsimon.vergauwen
09/12/2022, 9:30 AMshift and thus also bind, ensure, ensureNotNull, ... everything in the Effect DSL and everything that is build on top ๐ฅณthanh
09/12/2022, 9:30 AMsimon.vergauwen
09/12/2022, 9:30 AMsimon.vergauwen
09/12/2022, 9:33 AMcount() ?
The API designed for this is:
context(EffectScope<String>)
fun count(): Int =
catch({ TODO() }) { ex: IllegalStateException ->
shift(ex.message)
}
And here I am using the reified variant to select IllegalStateException as a partial function ๐thanh
09/12/2022, 9:36 AMcount , there is some Error , but depend on each logic function, I want to map it to some different DomainError . That's why mapLeft here is so convenient.simon.vergauwen
09/12/2022, 9:38 AMrecover.
context(Shift<E>)
suspend fun count() = 1
context(Shift<E2>)
suspend fun logic(): Int =
recover({ count() }) { e: E ->
shift(e.toE2())
}
fun E.toE2(): E2 = TODO()simon.vergauwen
09/12/2022, 9:38 AMrecover allows you to do what mapLeft does but in a DSL stylesimon.vergauwen
09/12/2022, 9:39 AMEffect, derived from the DSL method ๐simon.vergauwen
09/12/2022, 9:39 AMcatch for Throwable and recover for typed errors, and recover allows you to transform the error type.simon.vergauwen
09/12/2022, 9:40 AMMonadError, all use-cases can be derived from them.thanh
09/12/2022, 9:42 AMsimon.vergauwen
09/12/2022, 9:42 AMshift yes ๐
simon.vergauwen
09/12/2022, 9:42 AMmapLeft otherwise?thanh
09/12/2022, 9:43 AMScopeEffect , with EitherScope, we can just mapLeft directly, right?simon.vergauwen
09/12/2022, 9:45 AMval x: Either<String, Unit> = ...
val y: Either<Int, Unit> =
x.mapLeft { it.length }
val x2: Effect<String, Unit> = ...
val y2: Effect<Int, Unit> =
x2.recover { shift(it.length) }simon.vergauwen
09/12/2022, 9:46 AMwithTimeout
coroutineScope
withContext
...
All these Kotlin APIs are DSL blocks, rather than extension methods like we used to do before or often see in Scala.thanh
09/12/2022, 9:57 AMsimon.vergauwen
09/12/2022, 9:58 AMsimon.vergauwen
09/12/2022, 9:58 AMthanh
09/12/2022, 9:59 AMStylianos Gakis
07/20/2023, 11:31 PMsimon.vergauwen
07/24/2023, 6:28 AMrecover for types errors, and catch for exceptions.