raulraja
09/09/2017, 3:09 AMfun <A> List<A>?.isNotEmpty(): Boolean =
this != null && this.size > 0
object test {
val x : List<Int>? = null
val xIsNotEmpty: Boolean = x.isNotEmpty()
//false
val y : List<Int>? = emptyList<Int>()
val yIsNotEmpty: Boolean = y.isNotEmpty()
//false
val z : List<Int>? = listOf(1)
val zIsNotEmpty: Boolean = y.isNotEmpty()
//true
}
Although I'm not a fan of nullable types in general, I think that when certain checks that are always a reocurring pattern like this...
1. Check something is in a given state
2. Return something based on that state
It calls for a better abstraction that removes the boilerplate and justifies the extension method. That is seen also as a Option#fold when both the absence case and the fulfilled value are contemplated to coalesce in a same return type:
Example from Option#fold
fun <B> fold(ifEmpty: () -> B, f: (A) -> B): B = when (this) {
is Option.None -> ifEmpty()
is Option.Some<A> -> f(value)
}
IMO the List interface in Kotlin could provide automatic extensions for all its combinators for <A> List<A>? because it already has the notion of an empty() value.
Folding values of type <A> over themselves is what the Monoid<List<A>> can do by means of ifEmpty = { Monoid.empty() } and ifNotEmpty = (a, b) -> Monoid.combine(a, b).
fold can be generalized for all type constructors not just List that can represent an empty value an a means of combine.