I am looking for a way to combine several validation errors using the raise DSL when there is no res...
u
I am looking for a way to combine several validation errors using the raise DSL when there is no result to return. While there is
forEachAccumulating
instead of
mapOrAccumulate
when I am only interested in the errors, there does not seem to be a similarly complementarey function to
zipOrAccumulate
, is there? What I suppose I need is something along those lines:
Copy code
fun RaiseAccumulate<MyError>.ensureIsValid(myIdString: String) =
        ensureAccumulate( // this function does not exist
            { ensure( someCondition1(myIdString) ) { IncorrectCondition1(myIdString) } },
            { ensure( Dsomecondition2(myIdString) ) { IncorrectCondition2(myIdString) } }
        )
a
at this moment, unfortunately you need to write something along the lines of
Copy code
zipOrAccumulate(
  { ensure(...) }
  { ensure(...) }
) { }
however, in the 2.0 to be released soon, you've be able to write much nicer code
Copy code
accumulate {
  ensureAccumulating(thing1) { ... }
  ensureAccumulating(thing2) { ... }
}
๐Ÿ‘ 1
๐ŸŽ‰ 1
๐Ÿš€ 1
r
Wow! That's great! I'm curious: whatโ€™s the returning type of the
ensureAccumulating
function? I mean, in case of an error, you need to return something to let the execution proceed
a
just
Unit
r
Ok. The semantic is different from
zipOrAccumulate
then. You canโ€™t return a valid object as the return of the
accumulate
function. Did I get it wrong?
a
no, you definitely can. The DSL in that case encourages using delegated properties
Copy code
accumulate {
  val name by validateName(rawName).bindOrAccumulate()
  val age by validateAge(rawAge).bindOrAccumulate()
  Person(name, age)
}
mind blown 1
r
Thanks, Alejandro ๐Ÿ™. I need to check the implementation to understand it better. By the way, itโ€™s a nice DSL improvement ๐Ÿ™Œ
a
the main "trick" is that by using delegated properties we can delay the "bind" aspect to the moment in which the first variable is read. The code above actually compiles under the hood to:
Copy code
accumulate {
  val name: Value<Name> = validateName(rawName).bindOrAccumulate()
  val age: Value<Age> = validateAge(rawAge).bindOrAccumulate()
  Person(name.getValue(), age.getValue())
}
during the
bindOrAccumulate
(or any other accumulation function) we simply accumulate any errors in a temporary list. In the first call to
getValue()
we check that list, and it's there's something, we just raise the corresponding set of errors. unfortunately this is something which drinks a lot from Kotlin's delegated properties feature; I'm sure you can transpose it to Swift, but I'm not so sure about other languages...
arrow intensifies 1
K 1
gratitude thank you 1
r
but Iโ€™m not so sure about other languages...
In fact, I was thinking about how to transpose it into Scala ๐Ÿ˜… By the way, big shout-out ๐Ÿ‘