По сути, все операции с ZIO, включая collectAll
и fold
, являются операциями над функциями, поскольку каждый ZIO по своей природе является в основном капризной функцией. В вашем случае ZIO[Console, Throwable, List[Int]]
- это функция, где Console
является входным параметром, а Throwable
/ List[Int]
является одним из двух возможных типов вывода. Когда вы используете комбинаторы, такие как collectAll
и fold
, вы в основном создаете новую функцию на основе других функций.
Следующим шагом является оценка этой новой функции путем передачи в нее входного параметра. В вашем случае этим входным параметром является любая черта, которая расширяет тип Console
. Как @slouc отразил в своем ответе, вы можете просто использовать DefaultRuntime
"runner" на вашем res0
, потому что среда по умолчанию (входной параметр в терминах функций), предоставляемая этим бегуном, реализует черту Console
.
import zio.DefaultRuntime
val runtime = new DefaultRuntime {}
runtime.unsafeRun(res0)
Существует еще один более явный способ предоставления этого Env с использованием обеспечения ZIO #, но вам все равно потребуется некоторое время выполнения для выполнения этой функции после этого.
Я также хочу отметить, что когда вы делаете println
внутри вашего fold
, вы фактически не используете черту Console
, которую вы предоставляете в качестве входного параметра, но вы используете обычную println
при условиивместо родной скалы. В базовом случае это не имеет значения, но в реальных приложениях вам нужно будет использовать putStrLn
, предоставленный Console
.