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?
CodePudding user response:
The issue here is that you've defined the operator function to return OpenEndRange<LocalDate>
rather than OpenEndedLocalDateRange
. 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 OpenEndRange
doesn't have the higher order functions defined for it (ClosedRange
doesn't have them defined as well). Int
has it because the operators return an IntRange
which indirectly extends Iterable<Int>
via IntProgression
and Iterable
has these higher order functions defined, so, the only missing piece is failing to return the correct type from your operator function.