mitch
09/11/2021, 2:13 AMdata class ExecutionPlan<out A>(val runPlan: suspend (PlanConfig) -> A) {
fun <B> flatMap(fn: (A) -> ExecutionPlan<B>): ExecutionPlan<B> = ...
// map, zip, traverse
// etc...
}
Prior to arrow 0.13 it was leveraging ExecutionPlan.monad().fx { … }.fix()
Now that is not available anymore and I’ve refactored the code to nested flatMaps.. which proliferated in the codebase, and is causing some pain..
// what we have now:
val plan = planA.flatMap { a ->
planB.flatMap { b ->
planC(a, b).flatMap { c ->
// ...
}
}
}
// what we want:
val plan = executionPlan {
val a = planA.bind()
val b = planB.bind()
val c = planC(a, b).bind()
c
}
I’m wondering how i might leverage delimited continuation to implement this?
fun interface ExecutionPlanEffect<E, A> : Effect<ExecutionPlan<A>> {
suspend fun <B> ExecutionPlan<B>.bind(): B = ???
}
thanks!!simon.vergauwen
09/11/2021, 8:09 AMflatMap
implemented?
data class ExecutionPlan<out A>(val runPlan: suspend (PlanConfig) -> A) {
fun <B> flatMap(fn: (A) -> ExecutionPlan<B>): ExecutionPlan<B> =
ExecutionPlan { config ->
val a = runPlan(config)
fn(a).runPlan(config)
}
}
If this is the case, than you can very easily implement a executionPlan
Effect DSL.
class ExecPlanSyntax(val config: ConfigPlan) {
suspend fun <A> ExecutionPlan<A>.bind(): A = runPlan(config)
}
And I assume there is a function like this to run the ExecutionPlan
.
operator fun <A> ExcutionPlan<A>.execute(plan: PlanConfig): A = fn(ExecutionPlan(plan), plan)
Now we can update our constructor to incorporate our DSL, and rewrite flatMap
using suspension.
data class ExecutionPlan<out A>(val runPlan: suspend ExecPlanSyntax.(PlanConfig) -> A)
ExecutionPlan {
val a = bind()
val b = f(a).bind()
}
simon.vergauwen
09/11/2021, 8:09 AMmitch
09/11/2021, 8:21 AM