```fun <E, A, B> Validated<E, A>.andTh...
# arrow
d
Copy code
fun <E, A, B> Validated<E, A>.andThen(next: (A) -> Validated<E, B>): Validated<E, B> =
    this.withEither { first ->
        first.flatMap { next(it).toEither() }
    }
j
The main problem I see is that it breaks consistency when you try to define
zip
with it. In particular this should hold:
Copy code
validatedA.zip(validatedB, f) ===
validatedA.flatMap { a -> validatedB.map { b -> f(a, b) } }
It is sometimes useful to break this invariant but it usually leads to confusion. This may not be a huge problem now that we have no more typeclasses (with typeclasses it is very important to follow this rule!). This function is undeniably useful (so much so that I believe we have
Validated.bind()
in the
either
effect which is basically the same just for effect blocks). Not sure what the others think about it....
2
where it is included even though it isn’t a law-abiding
bind
instance
r
I’m personally happy with bind only because it’s explicit that the shortcircuit makes you loose the ability to accumulate errors. In the past iI have been bitten by andThen on Validated where I was assuming accumulation. I wonder if there is a version where it does accumulation on E automatically, that I’d find more useful but the regular version over Validated I find confusing.
d
you still get accumulation inside the
next
arg, right?
you just don’t accumulate from
this
into
next
r
Yes, the last part is what I find confusing , it’s the same as Either flatMap and we already have utlities to go to either and to bind validated in context that are explicit about short-circuiting.
In whatever case if you want to propose an implementation and open an issue we can further discuss it and get others opinion
👍 1