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.