Norbi
03/28/2023, 6:15 PMrecover()
and catch()
functions? Why isn't everything fold()
?
2. When is the type parameter B
and parameter transform
of fold()
is useful? Wouldn't it be enough to have
// Just an example, this function is not present is Arrow
inline fun <Error, A> fold(
@BuilderInference block: Raise<Error>.() -> A,
recover: (error: Error) -> A,
catch: (throwable: Throwable) -> A = { throw it }
)
and handle the transformation after the fold()
call?
The above is very similar to the actual recover()
function:
public inline fun <Error, A> recover(
@BuilderInference block: Raise<Error>.() -> A,
@BuilderInference recover: (error: Error) -> A,
@BuilderInference catch: (throwable: Throwable) -> A,
): A = fold(block, catch, recover, ::identity)
These questions popped up because I don't like the naming of the recover()
and catch()
functions.
I almost always use recover()
but it is a bit strange that it also has a parameter named recover
. So although the core function is fold()
, I never use it because recover()
with the transform = ::identity
argument seems to be appropriate always...
Thanks.fold
a well-known FP terminology? (So why not run()
or execute()
or perform()
or ...?)simon.vergauwen
03/28/2023, 6:49 PMfold
is useful when you need to align types after user code, so when building custom DSLs. I've only really needed it in one place, ior. So recover
is probably sufficient in 99,99% of the cases. It's also the natural operation for Raise
. Where you raise
and recover
• recover
with 3 parameters, is basically just an alias for fold
with ::identity
.fold
is indeed a common name in FP for this kind-of operation, but seems foreign to use all-over code so recover
seems to make more sense. Where you normally only need recover
or catch
in regular code, and even that only occasionally. Where typically most code exists out of flatMap
most of the time, but in this case it's just regular code and flatMap
is not needed.recover
with a recover
parameter is perhaps a bit unfortunate, but I am not sure what a better name would be. At least at this point it's consistent with all other functions and parameter names.
In the end like you said everything is just fold
but with different combinations of arguments. The reason for transform
is just that you can align the value returned from block
, recover
and catch
to a different type such as shown in Ior
.ior
can be rewritten with recover
😅
So the transform
parameter could be dropped but I would be in favor of recover
rather than fold
and that still brings the question of parameter name 🤔Norbi
03/28/2023, 7:03 PMrecover()
, it seems that I was the only one not completely satisfied with it 🤔 🙂simon.vergauwen
03/28/2023, 7:04 PMrecover
? From your answer it sounds like you're not fan of the parameter name recover
resulting in:
fun Raise<String>.example(): Int = 1
recover(
block = { example() },
recover = { str -> str.length }
)
Norbi
03/28/2023, 7:08 PMeffect {
...
}.recover {
...
}.bind()
can also be used which has a nice syntax imho 🙂bind()
😕simon.vergauwen
03/29/2023, 6:37 PM