@@ -10,6 +10,7 @@ import scala.util.boundary
1010import scala .annotation .implicitNotFound
1111import scala .Conversion .into
1212import scala .util .boundary .Label
13+ import steps .result .Result .eval .break
1314
1415/** Represents either a success value of type `T` or an error of type `E`. It
1516 * can be used when expecting results that have errors that should be inspected
@@ -457,6 +458,51 @@ object Result:
457458
458459 // Boundary and break
459460
461+ trait Evaluator [Impl [+ _,+ _]]:
462+ self =>
463+ type Success [+ T ]
464+ type Failure [+ E ]
465+
466+ inline def foldValue [T , E ](impl : Impl [T , E ])[U ](inline onSuccess : T => U , inline onFailure : Failure [E ] => U ): U
467+ inline def failure [E ](error : E ): Failure [E ]
468+
469+ extension [T , E ](
470+ using @ implicitNotFound(
471+ " `break` cannot be used outside of the `Result.apply` scope."
472+ )
473+ label : boundary.Label [Failure [E ]])(impl : into[Impl [T , E ]]) {
474+ final inline def ok : T = foldValue(impl)(t => t, boundary.break(_))
475+ }
476+
477+ trait EvaluatorCompanion [Impl [+ _,+ _]]:
478+
479+ final inline def raise [E ](using eval : Evaluator [Impl ])(using
480+ @ implicitNotFound(
481+ " `raise` cannot be used outside of the `Result.apply` scope."
482+ )
483+ label : boundary.Label [eval.Failure [E ]]
484+ )(inline err : into[E ]): Nothing = boundary.break(eval.failure(err))
485+
486+ final inline def break [T , E ](using eval : Evaluator [Impl ])(using
487+ @ implicitNotFound(
488+ " `break` cannot be used outside of the `Result.apply` scope."
489+ )
490+ label : boundary.Label [Impl [T , E ]]
491+ )(inline res : into[Impl [T , E ]]): Nothing = boundary.break(res)
492+
493+ given resultEvaluator : Evaluator [Result ] with
494+ type Success [T ] = Ok [T ]
495+ type Failure [E ] = Err [E ]
496+
497+ inline def foldValue [T , E ](impl : Result [T , E ])[U ](inline onSuccess : T => U , inline onFailure : Err [E ] => U ): U =
498+ impl match
499+ case Ok (value) => onSuccess(value)
500+ case err : Err [E ] => onFailure(err)
501+
502+ inline def failure [E ](error : E ): Err [E ] = Err (error)
503+
504+ object eval2 extends EvaluatorCompanion [Result ]
505+
460506 // Currently under its own object `eval` due to https://github.com/scala/scala3/issues/20126
461507
462508 /** Evaluates `body`, returning the output as an [[Ok ]] value.
0 commit comments