ZIO[Database, DBError, User] = ??? def getTasks(user: User): ZIO[TaskApi, ApiError, List[Task]] = ??? // ZIO を合成する def getActiveUserTasks(userId: String): ZIO[Database & TaskApi, DBError | ApiError, List[Task]] = for { user <- getUser(userId) tasks <- getTasks(user) } yield tasks // 全てのZIO のR, E が合わさったZIO が返却される // ZIO を実行する def executeProgram() = { val runnable: ZIO[Any, DBError | ApiError, List[Task]] = getActiveUserTasks("id-123") .provide(Database.instance, TaskApi.instance) .catchAll { case dbError: DBError => ??? case apiError: ApiError => ??? } Unsafe.unsafe { implicit unsafe => Runtime.default.unsafe.run(runnable).getOrThrowFiberFailure() } } Scala はいいぞ 14