I want to use higher order functions like map for open end ranges.
val from = LocalDate.now().minusDays(10)
val to = LocalDate.now()
(from ..< to).forEach(::println)
I tried to copy an example for ClosedRange<LocalDate> but it does not work.
package de.otto.di.extensions
import java.time.LocalDate
class OpenEndRangeLocalDateIterator(
startDate: LocalDate,
private val endExclusive: LocalDate,
private val stepDays: Long
) : Iterator<LocalDate> {
private var currentDate = startDate
override fun hasNext() = currentDate.plusDays(stepDays) <= endExclusive
override fun next(): LocalDate {
val next = currentDate
currentDate = currentDate.plusDays(stepDays)
return next
}
}
@OptIn(ExperimentalStdlibApi::class)
class OpenEndLocalDateRange(
override val start: LocalDate,
override val endExclusive: LocalDate,
private val stepDays: Long = 1
) : Iterable<LocalDate>, OpenEndRange<LocalDate> {
override fun iterator(): Iterator<LocalDate> =
OpenEndRangeLocalDateIterator(start, endExclusive, stepDays)
infix fun step(days: Long) = OpenEndLocalDateRange(start, endExclusive, days)
}
infix operator fun LocalDate.rangeUntil(to: LocalDate): OpenEndLocalDateRange =
OpenEndLocalDateRange(this, to)
It is implemented for Int so I assume it must be possible somehow. How can I achieve this?
The issue here is that you've defined the operator function to return
OpenEndRange<LocalDate>rather thanOpenEndedLocalDateRange. If you change the return type of your operator function that should fix the issue.The reason why it isn't working as is is because
OpenEndRangedoesn't have the higher order functions defined for it (ClosedRangedoesn't have them defined as well).Inthas it because the operators return anIntRangewhich indirectly extendsIterable<Int>viaIntProgressionandIterablehas these higher order functions defined, so, the only missing piece is failing to return the correct type from your operator function.