-
Notifications
You must be signed in to change notification settings - Fork 6
Open
Labels
Description
Do YAES need something like a bridge? (btw open question)
(inspired by Kyo’s Cats / ZIOs bridges and the community PoC gist https://gist.github.com/mucaho/d80551dd0b62c59ce0e2186608482577)
Motivation
Kyo shows a proven migration path by shipping lightweight bridges (kyo-cats, kyo-zios) that lift TF programs into Kyo effects and lower them back when needed.
A recent community gist demonstrates how the same idea can work for YÆS by hand-rolling small capability wrappers and providing Monad, Raise, Stateful, etc. instances.
Giving YÆS a first-class, batteries-included TF interop module 😄 will:
- remove the “lock-in” fear for existing Cats/ZIO codebases;
- unlock immediate use of the vast Typelevel ecosystem (http4s, Doobie, FS2, etc.)
Scope / Deliverables
| # | Deliverable | Details |
|---|---|---|
| 1 | yaes-interop-cats module |
Artifacts: "in.rcard.yaes" %% "yaes-interop-cats" % x.y.z.• Effect Cats exposing Cats.get(io: IO[A]): A and Cats.run { … }: IO[A].• Type-class instances: given Monad[[A] =>> Cats ?=> A], given cats.effect.Sync[[A] =>> Cats ?=> A], given cats.mtl.Raise[[A] =>> Cats ?=> A, E], etc. |
| 2 | yaes-interop-zio module |
Mirror of (1) but for ZIO. • Zios.get(task: Task[A]): A / Zios.run { … }: Task[A].• Propagate cancellation & interruption semantics like zio.interop.catz |
| 3 | Capability lifting helpers | Utilities to convert YaesFiber ⇆ cats.effect.Fiber, YaesFiber ⇆ zio.Fiber, preserving cancel semantics. |
| 4 | Law-testing & Examples | Discipline-based tests proving Monad/Sync laws; example that runs http4s + Doobie inside YÆS via the bridge |
| 5 | Docs & Migration Guide | README for each module + cookbook: “Refactor CE program to YÆS in 3 steps”. Reference the PoC gist for deeper rationale |
Non-goals (for this ticket)
- General mtl-style or BIO/Tofu support.
API Sketch (Cats bridge)
object Cats:
type Cats = Yaes[Cats.Unsafe]
def get[A](io: cats.effect.IO[A])(using Cats): A =
Cats(io) // lift
def run[A](block: Cats ?=> A): cats.effect.IO[A] =
Yaes.handle(block)(
new Yaes.Handler[Cats.Unsafe, A, cats.effect.IO[A]]:
def handle(p: Cats ?=> A) =
cats.effect.IO.blocking(p(using Yaes(unsafe)))
)
private val unsafe: Unsafe = (io: cats.effect.IO[?]) => io.unsafeRunSync()
trait Unsafe:
def apply[A](io: cats.effect.IO[A]): Amucaho and lhns