```validatorAE.validateEmailWithRules(user.email)....
# arrow
p
Copy code
validatorAE.validateEmailWithRules(user.email).bind()
cityShouldBeValid(user).bind()
loginShouldNotExit(user).bind()
g
But the raiseError inside these functions is done on
validatorAE
, so this is not failing-fast
Copy code
fun <F, S> EffectValidator<F, S, ValidationError>.cityShouldBeValid(user: User): Kind<F, Kind<S, Boolean>> = fx.async {
    repo.run {
        val cityValid = user.isUserCityValid().bind()
        if (cityValid) validatorAE.just(cityValid)
        else validatorAE.raiseError(UserCityInvalid(user.city).nel())
    }
}
p
validatorAE.validateEmailWithRules(user.email)
will short if it fails
.bind()
is equivalent to putting the rest of the function as the
flatMap
body
g
but with
bind()
, the
flatMap
is done on
F
not on the
Either
which is returned from
validateUserWithRules
so it essentially doen’t fail-fast and ignores any error from 
validateEmailWithRules
p
call the two binds first, then put them inside a
flatMap
of
validatorAE
is that what you mean?
g
that defeats my fail-fast purpose, I dnt want db calls to be happening
p
Copy code
val a = cityShouldBeValid(user).bind()
val b = loginShouldNotExit(user).bind()

validatorAE.validateEmailWithRules(user.email).flatMap { a.flatMap { b } }
I need more types inline inside
validateUserWithRules
otherwise it's hard to know
g
you need more details?
This branch of my repo has the entire code, there are unit tests as well
This is a small poc repo, but pls let me know if something is not clear
p
these are still untyped
the repo
I'd like that same snippet you posted, with every step of the way annotated
no inference
so I understand what your data shapes are better
g
oh, u need the return types explicit, right?
p
Copy code
val a = cityShouldBeValid(user).bind()
val b = loginShouldNotExit(user).bind()
what is
a
and
b
after binding there?
yes
g
got it, will do a quick push doing that, 5 mins
p
thanks
line 22, annotate the method return too
and any intermediates you can find
g
Yes, sure
I hv pushed with types
p
okay, so on the latest version
Copy code
validateEmailWithRules
  .flatMap { cityShouldBeValid }
  .flatMap { loginShouldNotExit }
that would work
it fails on the first one that fails from the three
and you can code golf to whatever semantics you want
Copy code
validateEmailWithRules
  .flatMap {
    Either.tupled(cityShouldBeValid, loginShouldNotExit)
  }
g
In the latest version, I added those variables
cityShouldBeValid
and
loginShouldNotExit
for clarity on types, as you review, but I dnt want to make those calls early on.
I dnt want the db calls to happen, if
validateEmailWithRules
fail
This is the reason I had to write a different function, without using
mapN
p
okay, then you have to convert from
Either
into a
Kind
with whatever properties you want
what you have is an EitherT problem
fun <F> EffectValidatorFailFast<F, ValidationError>.validateUserWithRules(user: User): EitherT<F, NonEmptyList<ValidationError>, Boolean>
Copy code
EitherT.fx(this).async {
  just(validateEmailWithRules)
    .flatMap(this) { cityShouldBeValid(user) }
    .flatMap(this) { loginShouldNotExit(user) }
}
something like that
I know it's not exactly like that
follow that shape
just(validateEmailWithRules)
is probably something else, you have to wrap the either in ``validateEmailWithRules`` into the Kind of
F
and just there will build an EitherT where the right side is an Either instead
so it may be lift or some other construct
g
Yes, I tried
EitherT
as well, but ran into compiler problems
as MF here is generic
Let me quickly ping u what I tried… Sorry for taking ur time, hope this problem feels interesting 🙂
p
hhahaha you have to fight the compiler until it works
understanding the semantics of
bind
and
flatMap
and how nested types interact
and it's not...delightful how they do
EitherT is a patch
follow what the compiler says until you reach a stability point
g
yes, it does feel like I will never use something like that in prod
p
you develop that skill over time
g
Ya, that is what these self made excercises help me
🙂