Fibers
E.fork(effect) starts an effect concurrently and returns an E.Fiber. fiber.join() is the fiber's value, failing with the fiber's own cause; fiber.wait() is its Exit and never fails; fiber.poll() peeks without waiting; fiber.interrupt() cancels it, lets its finalizers run and returns the Exit; E.yield_now() lets other fibers take a turn. Fibers are asyncio tasks underneath, so fork is async only and a forked run starts with a fresh environment: provide what it needs.
@E.
def () -> E.[, ]:
fiber = yield from E.(()) # runs concurrently
= yield from ()
= yield from .() # Effect[int, FetchError]
return + More examples: test_fiber.py.