Tom Davis
06/02/2023, 1:46 PMValidatedNel<A, B>
i can thread an argument through them, returning ValidatedNel<A, B>
where B
is the return value from the final function in the list if all succeed, otherwise the errors? feels like i should be able to do this with foldMap()
...Alejandro Serrano Mena
06/02/2023, 1:47 PMmapOrAccumulate
and bind
Alejandro Serrano Mena
06/02/2023, 1:48 PMmapOrAccumulate(listOfFunctions) { fn ->
fn(argument).bind()
}.bind().last()
Alejandro Serrano Mena
06/02/2023, 1:50 PMmapOrAccumulate
will iterate through the list and accumulate the errors
• the bind()
inside the block is necessary to “embed” the Validated
result into Raise
• the outer bind()
to short-circuit in case the mapOrAccumulate
returns a Invalid
• and then you use last()
to get the last elementTom Davis
06/02/2023, 1:55 PMfn()
into the next one, not call each one with argument
.Youssef Shoaib [MOD]
06/02/2023, 2:51 PMlistOfFunctions.fold(firstArg) { arg, fn -> fn(arg).bind() }
While making sure you're inside a Raise<Nel<A>>
Youssef Shoaib [MOD]
06/02/2023, 2:53 PMRaise<Nel<A>>.(B) -> B
instead of (B) -> ValidatedNel<A, B>
(which are semantically equivalent) then you can remove the bind as well.
Conceptually, your functions are (B) -> B
but with the possibility of raising a Nel<A>
. Once that's your mental framework, it's easy to see that fold
is the right option to transform a List<(B) -> B>
and a first argument B
into a return value of B
, and handling the Nel<A>
becomes merely an implementation detail, yet your functions are still referentially transparent and pure.Tom Davis
06/02/2023, 4:42 PMYoussef Shoaib [MOD]
06/02/2023, 6:30 PMAlejandro Serrano Mena
06/02/2023, 7:49 PM