Comments (11)
No zio/zio#7122.
from zio-prelude.
Hmmm, I think other people had the opposite expectation. You start with a Validation[E, A]
, which has a single E
in the type parameter but models the possibility of multiple failures, you get back an IO[E, A]
which also has a single E
in the type parameter and also can model the possibility of multiple failures. If anything it seems like we are not properly taking advantage of the data type if it has its own way of representing parallel failures and we are ignoring that.
Also, I think normally the reason you use data types like this is because you want to defer error handling until later which you can easily do. This also improves the ability to compose the resulting ZIO
with other ZIO workflows that fail with an E
instead of a NonEmptyChunk[E]
.
This is also consistent with the definition of this operator on ZPure
, which also models the possibility of multiple parallel failures and also converts this to ZIO
using ZIO's Cause
data type.
from zio-prelude.
@kurtlogan Hi! The toZIO
operator does preserve all of the failures using ZIO's Cause
data type. You can expose them with the parallelErrors
operator on ZIO
.
from zio-prelude.
I'm using parallelErrors
at the moment however it feels unintuitive to have to, I reach for Validation
because I care about all the failures equally and that doesn't change when I convert it to the ZIO
data type
from zio-prelude.
They do both model the possibility of multiple failures but Validation
treats all failures equally, If I were to call mapError
on Validation
I would apply the function to all failures and with fold
I would need to handle a NonEmptyChunk[E]
in the first argument where as with ZIO
this is not the case.
So as an example the following would produce different results while looking almost identical
Validation
.validateAll(List(Validation.fail("failure 1"), Validation.fail("failure 2"))
.mapError(_ + " group1")
.toZIO
Validation
.validateAll(List(Validation.fail("failure 1"), Validation.fail("failure 2"))
.toZIO
.mapError(_ + " group1")
Also, with this implementation of toZIO
the compiler no longer helps get to a correct solution and the developer is expected to know that the failures are not all expressed in the type signature, which could be especially confusing in large projects or when using libraries. The fact that they can be easily compsed could also lead to more confusing as you are not forced to handle the failures.
I always thought the E
in ZIO
represented the recoverable failures, in the case of Validation
this would be all the failures not some arbitrary E
. Of course that is based on my understanding of ZIO
which may not be correct
from zio-prelude.
Those two actually are the same (there was a recent bug fix related to this that will be available in the next release).
Cause
can preserve multiple parallel failures and they are both recoverable failures that are of equal "priority". ZIO
is more flexible than Validation
in that you can use operators that handle a single error, such as fold
, but you can also always work with all errors using operators such as foldCause
or parallelErrors
.
What I keep coming back to is if you asked what is the idiomatic way in ZIO to represent parallel errors, it would definitely be using Cause
. For example, ZIO.failCause(Cause.fail("failure 1") && Cause.fail("failure 2"))
. And that is in fact how we capture parallel errors, such as when we do ZIO.fail("failure 1").zipPar(ZIO.fail("failure 2"))
. This is a data type that described parallel errors. So that is how it should be represented.
It can definitely be helpful to "expose" the parallel errors, which it sounds like you are looking for, and there is an operator for that in parallelErrors
.
from zio-prelude.
there was a recent bug fix related to this that will be available in the next release
btw is this the one you have in mind?
from zio-prelude.
No worrys, thanks for taking the time to explain it to me
from zio-prelude.
Just wanted to bump this again because I'm continuously running into it when using Validation to handle form/json data where I always want to return all errors back to the user, not a single one. I guess in other words I don't consider my error type to be E
but rather NonEmptyChunk[E]
, but would like to use Validation's ability to combine them for me.
@adamgfraser I can totally understand your reasoning, but perhaps it would make sense to expose another operator such as toZIOAllErrors
that exposes the NonEmptyChunk[E]
as the error?
(what also makes the current situation somewhat unergonomic that that parallelErrors
exposes ::[E]
rather than a NonEmptyChunk[E]
)
from zio-prelude.
@frekw Will take a look but yes if you want to do this in your own code you can always do validation.toZIO.parallelErrors.map(NonEmptyChunk.fromCons)
or extract that into your helper method so I think you can do exactly what you want.
from zio-prelude.
Yes I 100% can, and am doing all the time, it just feels like Prelude could make it easier 🙂
from zio-prelude.
Related Issues (20)
- `ZIO.foreachPar(nonEmptyList)(f)` doesn't compile HOT 3
- Opaque type residing in the same package object as Newtype/Subtype breaks compilation HOT 1
- Add implementation of Free HOT 2
- Newtypes: Composed assertions on String values do not work at compile time HOT 3
- typeclass instances for zio.Config HOT 1
- [Scala 2.13] Subtype of Newtype cause cyclic subtyping error HOT 19
- Broken forEach on CovariantIdentityBoth
- java.lang.NoSuchMethodError MyType$.$anonfun$assertion$1$adapted(Ljava/lang/Object;)Lscala/util/Either;
- make-macro behaves unexpectedly with jsoniter-scala HOT 2
- Split out Newtype+Subtype functionality to separate, smaller library HOT 6
- Custom error message for Assertion HOT 2
- Incorrect debug value for java.util.concurrent.TimeUnit.MINUTES
- The `abstraction-diagrams` ID Doesn't Exist HOT 3
- Check Website Build Before Publishing The Documentation Project
- Change scope of ClassTagWrapper in NewType to public?
- `.wrapAll` for multi-type types
- Problem with `===` and Slick
- NonEmptySet#removeNonEmpty is does not remove the requested item
- Extension methods on NewType not working since 1.0.0RC16 HOT 1
- SortedSet syntax
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from zio-prelude.