<@U0FFA2HMM> ``` fun &lt;A&gt; List&lt;A&gt;?.isN...
# codingconventions
r
@prat
Copy code
fun <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
Copy code
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
.
👍 2