Closed LVMVRQUXL closed 1 year ago
For flexibility purpose, we decided to give the minimum behaviour to the types: a function for building the type and overrides only. Other features will be implemented as extension functions.
This new hierarchy should have the following design (also available in this playground):
import kotlin.jvm.JvmInline
import kotlin.random.Random
// ---------- Number ----------
sealed interface ExplicitNumber<out N : Number> {
val value: N
}
sealed interface NonZeroNumber<out N : Number> : ExplicitNumber<N>
sealed interface PositiveNumber<out N : Number> : ExplicitNumber<N>
sealed interface NegativeNumber<out N : Number> : ExplicitNumber<N>
sealed interface StrictlyPositiveNumber<out N : Number> : NonZeroNumber<N>, PositiveNumber<N>
sealed interface StrictlyNegativeNumber<out N : Number> : NonZeroNumber<N>, NegativeNumber<N>
// ---------- Int ----------
sealed interface ExplicitInt : ExplicitNumber<Int>
fun NonZeroInt(value: Int): Result<NonZeroInt> = NonZeroIntImplementation of value
sealed interface NonZeroInt : ExplicitInt, NonZeroNumber<Int> {
object Exception : IllegalArgumentException("Given integer should be other than zero.")
}
@JvmInline
private value class NonZeroIntImplementation private constructor(override val value: Int) : NonZeroInt {
override fun toString(): String = value.toString()
internal companion object {
internal infix fun of(value: Int): Result<NonZeroInt> = value.takeIf { it != 0 }
?.let(::NonZeroIntImplementation)
?.let { Result.success(it) }
?: Result.failure(NonZeroInt.Exception)
}
}
sealed interface PositiveInt : ExplicitInt, PositiveNumber<Int>
sealed interface NegativeInt : ExplicitInt, NegativeNumber<Int>
sealed interface StrictlyPositiveInt : ExplicitInt, NonZeroInt, PositiveInt, StrictlyPositiveNumber<Int>
sealed interface StrictlyNegativeInt : ExplicitInt, NonZeroInt, NegativeInt, StrictlyNegativeNumber<Int>
fun main() {
val x: NonZeroInt = Random.nextInt()
.let(::NonZeroInt)
.getOrThrow()
println("x = $x")
NonZeroInt(0)
.getOrThrow()
}
Done.
We will finally try to represent all declarations related to numbers using only generics and the hierarchy of ExplicitNumber
.
The goal is to be able to do more with less types.
For doing so, we now need to:
ExplicitNumber
Done.
Introduce this new hierarchy as an alpha feature instead.
This new hierarchy will be designed with interfaces and extension functions instead of sealed interfaces and member functions for letting the ability to extend it without changing its behaviours.
Done.
We will revert the changes introduced by this issue, because the kotlin.Number
type is not sealed and doesn't provide any operation for its children types, except explicit conversions.
For Kotools Types 3.2, we will only focus on the explicit types for the kotlin.Int
type.
Description
Introduce a new number hierarchy with the following types:
ExplicitNumber<T : Number>
representing explicit numbersNonZeroNumber<T : Number>
representing numbers other than zeroPositiveNumber<T : Number>
representing positive numbersStrictlyPositiveNumber<T : Number>
representing strictly positive numbersNegativeNumber<T : Number>
representing negative numbersStrictlyNegativeNumber<T : Number>
representing strictly negative numbers.Checklist
kotools.types.number
package as an alpha feature.Work in progress
section in changelog.