Sequence generator as extension function call does not work with "sink type mismatch"

I am playing around with trying to create a sequence from a single value Long

appended to LongRange

. It works:

val seq = buildSequence<Long> {
    yield(2)
    yieldAll(3L..5)
}

      

But in trying to generalize it, I cannot structure an extension function that I can successfully call:

infix fun Long.join(R: LongRange): Sequence<Long> {
    val start = this
    return buildSequence<Long> {
        yield(start)
        yieldAll(R)
    }
}

      

When I try to call it:

(2 join 3..5).forEach { /* do something */ }

      

I get

Error: (26, 20) Kotlin: Unresolved reference. None of the following candidates are applicable due to a receiver type mismatch: public infix fun Long.join (R: LongRange): a sequence defined in main.kotlin

The compiler seems to recognize that the function signature is close to what I am trying to achieve, but I am clearly fuzzy which means "receiver type mismatch".

+3


source to share


1 answer


A receiver type mismatch error means that what is passed as a receiver to the extension function (that is, that it is called) does not match the declared receiver type.

Kotlin, unlike Java, does not promote numbers to wider numeric types, and you should use Long

literals
in your code where expected Long

:

(2L join 3L..5).forEach { /* do something */ }

      

Here, use 2

as a sink is not an option as expected Int

. But in 3L..5

using 5

this is ok, because there is an Long.rangeTo

overload that takes Int

and returns a LongRange

.




The only exception when there is auto-propagation is when you assign a literal Int

to a variable of a different integral type and when you pass a literal Int

as a function argument that another integral type expects (as said above, it doesn't work with receivers).

val a: Long = 5 // OK

fun f(l: Long) { }
f(5)            // OK

val b = 5
val c: Long = b // Error
f(b)            // Error

      

+4


source







All Articles