acumulación — zipOrAccumulate & compañía
La validación quiere todos los errores, no solo el primero. Estas
operaciones ejecutan todas las ramas y concatenan los fallos en un
NonEmptyList — el sustituto que Arrow 2.x ofrece en lugar de
un tipo Validated aparte.
Lección
Dentro de either<Nel<E>, _>(...) — cualquier
ámbito cuyo tipo de error sea un NonEmptyList — el ámbito
gana el vocabulario de acumulación:
r.zipOrAccumulate2..5(branches…, combine)— ejecuta N ramas independientes, informa de todos los fallos y combina los aciertos.r.accumulate((acc) { … })— la forma general: ejecuta las ramas conacc.accumulating(block)y después lee el.valuede cada resultado. Si algo falló, leer un valor (o llegar al final del bloque) eleva la lista completa de errores.r.mapOrAccumulate(items, transform)— valida una colección entera en modo fail-slow.r.bindNel(eitherNel)— desenvuelve unEitherNel, elevando todos sus errores de golpe;someEither.toEitherNel()permite introducir un valor fail-fast.
El contrato es el de Arrow: todas las ramas se ejecutan (los errores se concatenan en el orden de las ramas), una rama que lanza una excepción en vez de elevar un error gana sobre la acumulación y, tras el primer error, los resultados correctos ya no se conservan: la iteración continúa solo para recoger los errores restantes.
Demo 1 · zipOrAccumulate2
Demo 2 · accumulate — la forma general
Demo 3 · mapOrAccumulate, bindNel & toEitherNel
Demo 4 · dependent — reglas que leen valores hermanos
Una rama no puede leer el Accumulated.value de una hermana
sin detonar — la única regla dura de la acumulación. Pero la validación
real tiene reglas dependientes ("un gasto necesita un
importe positivo"), y por eso los formularios acababan bajando
a un guard manual if (!acc.hasErrors).
acc.dependent(block) le pone nombre a ese guard: el bloque
corre solo cuando todas las ramas anteriores tuvieron éxito — así las
lecturas de .value hermanas dentro son seguras por
construcción — y se salta por completo en caso contrario. (Sin
contraparte en Arrow; sus usuarios escriben el mismo guard a mano.)
Pruébalo tú
Ejercicio: completa las dos ramas de signup para que la
segunda llamada informe de ambos fallos.
NonEmptyList — el portador de los errores ·
Either × pipelines — validación fail-slow sobre cadenas fx(), con concurrencia ·
either & Raise — el ámbito fail-fast que esto extiende ·
errores tipados — guía completa