Hi, is there a way to call suspend function inside
eval's
map and flatmap. I have this code but it doesn't compile as
doSomething()
can only be called withing coroutine body.
Copy code
import arrow.core.Eval
import kotlinx.coroutines.runBlocking
fun main(): Unit = runBlocking {
Eval.now(10)
.map { doSomething() }
.value()
}
private suspend fun doSomething(): Int {
println("do something")
return 20
}
s
simon.vergauwen
06/29/2021, 1:51 PM
Hey @ds3fdfd3,
It's not possible to call `suspend`'ing code inside
Eval
since it's a deferred execution monad.
What is your use case of combining
Eval
with
suspend
?
d
ds3fdfd3
06/29/2021, 2:10 PM
Hi @simon.vergauwen,
my use case is something like this. Underlying database library that I
am using requires that for transactions, we pass on all the items that
we want to put/delete together. To solve this I was trying to write a
domain specific method which would take multiple 'Evals' generating put/delete items.
However, in certain cases, we have to make another suspending database call from within the
domain specific method. E.g. caller provides an Eval which gives a 'deviceId' to be deleted, however, to properly delete this deviceId we need its user, hence we make an internal call to database to get the user.
Basically:
eval.map { deviceId ->
val user = getUserForDevice(deviceId) //suspend call
doSomethingWithUserAndDevice(user, deviceId)
}
ds3fdfd3
06/29/2021, 2:11 PM
I hope this makes some sense. 😁
s
simon.vergauwen
06/30/2021, 7:02 AM
I think instead of passing
Eval
around, in this case you'd just want to pass around
suspend () -> A
instead.
That way everything is still lazy, and you have full
suspend
support without using a data type like
Eval
. Which doesn't support this usecase.
simon.vergauwen
06/30/2021, 7:02 AM
Eval
is meant to build pure stacksafe functions that cannot be written with
tailrec
.
d
ds3fdfd3
06/30/2021, 9:06 AM
Thanks, I am updating the function with suspend functions rather than