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.Norbi
03/28/2023, 6:44 PMfold 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.simon.vergauwen
03/28/2023, 6:50 PMfold 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.simon.vergauwen
03/28/2023, 6:53 PMrecover 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.simon.vergauwen
03/28/2023, 6:57 PMior 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 PMNorbi
03/29/2023, 6:01 PMeffect {
...
}.recover {
...
}.bind()
can also be used which has a nice syntax imho ๐Norbi
03/29/2023, 6:30 PMbind() ๐simon.vergauwen
03/29/2023, 6:37 PM