arrow-core icon indicating copy to clipboard operation
arrow-core copied to clipboard

["Request"] Add a `fold` function for nullable types

Open LordRaydenMK opened this issue 3 years ago • 4 comments

What version are you currently using?

0.11

What would you like to see?

When moving from Option to using nullable types, the fold function is missing so you end up doing:

?.let { ... } ?: run { ... }

We can add a function:

fun <A, B> A?.fold(ifNull: () -> B, ifPresent: (A) -> B): B =
    this?.let(ifPresent) ?: ifNull()

that would make this a bit easier to work with.

Source: https://github.com/arrow-kt/arrow-core/pull/239#discussion_r495479486 suggested by @pablisco

You can also see the pattern in the PR.

LordRaydenMK avatar Sep 27 '20 10:09 LordRaydenMK

If we mirror the current Option API for nullables it will make migration much easier as we can use ReplaceWith without any compilation errors after the replacement. Aditionally, having map, flatMap and such would be a nice companion to stdlib

pablisco avatar Sep 27 '20 17:09 pablisco

Can we make these inline?

raulraja avatar Sep 27 '20 23:09 raulraja

After more time than I would like to admit, I realised one problem... A? is contravariant of all Kinded types, so it adds ambiguity and, for obvious reasons, it cannot be resolved 🤦

Maybe if we call it foldNull? I'm uncertain if there will be inline classes in the future. This indicates that could be (maybe?) https://github.com/Kotlin/KEEP/blob/master/proposals/inline-classes.md#inline-classes-over-nullable-reference-types

That would be the ideal solution, in reality, so we can avoid polluting the global scope with extension functions like these.

pablisco avatar Oct 02 '20 23:10 pablisco

Yes, we currently also have this issue with mapN defined in Nullable.kt it's conflicing with mapN for List and possibly other top-level methods such as mapN, tupledN we might want to add for other types. I don't think it makes sense to add such extensions on A?, but arity builders functions like mapN which require a lot of boilerplate I do think it makes sense.

this?.let(ifPresent) ?: ifNull() is more Kotlin idiomatic than this.fold(ifPresent, ifNull).

nomisRev avatar Dec 20 '20 14:12 nomisRev