Coming from Arrow¶
If you're already using Arrow's parZip for parallel execution, KAP can complement or replace it for multi-phase orchestration. This guide shows the migration path.
KAP + Arrow: complementary, not competing¶
KAP's kap-arrow module uses Arrow's Either and NonEmptyList. You don't have to choose one or the other:
dependencies {
implementation("io.github.damian-rafael-lattenero:kap-core:3.0.0")
implementation("io.github.damian-rafael-lattenero:kap-arrow:3.0.0") // uses Arrow Core
}
Simple parallel: parZip → combine¶
Almost identical. KAP's combine is Arrow's parZip equivalent.
Type-safe ordering: parZip → kap + .with¶
Multi-phase: sequential parZip → flat chain¶
This is where KAP shines. Arrow requires separate parZip calls with intermediate variables:
// Phase 1
val (user, cart) = parZip(
{ fetchUser() }, { fetchCart() },
) { u, c -> Pair(u, c) }
// Phase 2 (barrier — just a suspend call)
val validated = validate(user, cart)
// Phase 3
val (shipping, tax) = parZip(
{ calcShipping() }, { calcTax() },
) { s, t -> Pair(s, t) }
val result = Result(user, cart, validated, shipping, tax)
@KapTypeSafe
data class Result(val user: User, val cart: Cart, val validated: Validated, val shipping: Shipping, val tax: Tax)
val result = kap(::Result)
.with { user from fetchUser() } // ┐ phase 1
.with { cart from fetchCart() } // ┘
.then { validated from validate() } // ── phase 2: barrier
.with { shipping from calcShipping() } // ┐ phase 3
.with { tax from calcTax() } // ┘
.evalGraph()
Value-dependent phases: nested parZip → .andThen¶
@KapTypeSafe
data class UserContext(val profile: String, val prefs: String)
@KapTypeSafe
data class Enriched(val recs: String, val promos: String)
val enriched = kap(::UserContext)
.with { profile from fetchProfile(userId) }
.with { prefs from fetchPrefs(userId) }
.andThen { ctx ->
kap(::Enriched)
.with { recs from fetchRecs(ctx.profile) }
.with { promos from fetchPromos(ctx.prefs) }
}
.evalGraph()
Validation: zipOrAccumulate → zipV¶
Features KAP adds over Arrow¶
| Feature | Arrow | KAP |
|---|---|---|
| Visible phases | No | .then / .andThen |
| Compile-time arg order | No | Typed function chain |
| Max arity | 9 | 22 |
timeoutRace |
No | Parallel fallback, 2.6x faster |
raceQuorum |
No | N-of-M consensus |
.settled() |
No | Partial failure tolerance |
.memoizeOnSuccess() |
No | Cache only successes |
| Parallel validation | zipOrAccumulate |
zipV (parallel + arity 22) |