Do we have something like this in Arrow? I tried t...
# arrow
t
Do we have something like this in Arrow? I tried to find but it seems missing.
Copy code
public fun <A, B, C> Either<A, B>.combine(SGA: Semigroup<A>, b: Either<A, C>): Either<A, Pair<B, C>>
s
the function exists for
Validated
and it's called
zip
https://arrow-kt.io/docs/apidocs/arrow-core/arrow.core/zip.html AFIK it doesn't exist for Either
t
thanks, I knew that, but also I feel like, the way we have to switch between
Validated
and
Either
is a bit annoying sometime ;(
s
👍 1
Do you have different use-cases?
t
Thanks Simon. I'm using similar strategy as your example. It works great. But in my experience there are some difficulty when introduce
Validated
to beginners.
s
Always interested in improving on that, but I personally don't think introducing such an API for Either would make this more clear.
👍 2
t
Agree, this api also introduce some complication as well.
r
I think in the future the use cases for validated like error accumulation can be added directly over Either when there is a NonEmptyList<E> on the Left side. Other than that Validated and Either are the same. This is something I think we should re-visit. Is there other use case that Validated covers and Either does not beside the operators for Error accumulation?
s
If we opt for such a API I would argue that we should drop
zip
for
Either
completely. Since
zip
is simply the following, but the snippet below doesn't even suffer from the
n-arity
issue
Copy code
either {
   transform(a.bind(), b.bind(), c.bind(), ...)
}
That raises another issue though. What about
traverse
does it accumulate, or not for "Either/Validated".
If we can remove API surface, and/or data types whilst still covering the same features/behaviour in a clear way I am pro.
t
I think
traverse
should work as normal, and additional
parTraverse
for error accumulation.
But maybe that will be confused with some other concurrency functionality.
s
It would conflict with
parTraverse
from Arrow Fx yes
👍 1
I am personally not a huge fan of
parMap
/
parTraverse
naming for error accumulation.
I always expect parallelism
p
would `nelMap`/`nelTraverse` work?
🤔 2
s
Hmm, I like this discussion thread! 🥳 To make a suggestion, and to stay within the Kotlin Std naming spirit I think something like
mapAccumulate
or
mapCollect
or something along those might be a good API name for such an API. If we can close the gap between
Validated
and
Either
we can seriously decrease the API surface 🤔 Is there a use-case for
Validated
except for
traverse w/ Monoid
or
zip w/ Monoid
? cc\\ @Alejandro Serrano Mena
a
I’ve never used it in any other place than either
zip
or `traverse`ing some data structure (maybe not a list, maybe a tree or something like that)
but indeed one could minimize the surface a lot by making something like
Validated<A, B> = Either<NonEmptyList<A>, B>
or something like that, and provide specific
mapAccumulate
which only work when
Either
has a list inside
s
right now
Validated
support any type on the left.... wouldn't that limit the left side to
NonEmptyList
?
🔝 1
s
Yes, introducing such a restriction seems unnecessary.
s
the way I see it, in terms of the data they carry
Validated
and
Either
are the same. We can convert between both of them without information loss. The differences are: •
Validated
lacks
flatMap
by design (it used to have
andThen
which was similar to
flatMap
) •
Either
has a
zip
that does NOT accumulate errors,
Validated.zip
accumulates errors •
Validated
accumulates errors and
Either
short circuits on the first error The short circuit VS error accumulation behaviour right now is based on the container type. If we were to merge both containers we would need some other way to trigger error accumulation VS short circuiting. I'm not sure what that would be and if it would actually make things simpler. 🙂
👍 1
t
So maybe I'm naive, but if we introduce two new functions for
Either
for errors accumulation, which can be
zipAcccumulate
and
traverseAccumulate
then we don't have to use
Validated
anymore. At least for my use cases and Simon's examples above.
3
s
I was curious how ZIO handles this as ZIO also doesn't have typeclasses and it's not constrained by them... ZIO itself doesn't have error accumulation, it only has the failing fast
zip
method. For accumulating errors they have
Validation
which is similar to
ValidatedNel
and
ZValidation
which is similar to
Validated
in ZIO Prelude https://zio.github.io/zio-prelude/docs/functionaldatatypes/
a
yes, having different
Either
and
Validated
is a common pattern, not only in ZIO, Haskell also follows that trend. But there are also reasons to keep the API simple and have just a single one