miha-x64
04/25/2020, 4:24 PMmiha-x64
04/25/2020, 4:25 PMinline fun <C : Comparable<C>, R> C.cmpFold(
other: C,
ifLess: () -> R,
ifEqual: () -> R,
ifGreater: () -> R
): R {
val cmp = this.compareTo(other)
return when {
cmp < 0 -> ifLess()
cmp == 0 -> ifEqual()
cmp > 0 -> ifGreater()
else -> throw AssertionError()
}
}
use sample:
`
println(a.cmpFold(b, ifLess = { "<" }, ifEqual = { "=" }, ifGreater = { ">" }))
Shawn
04/25/2020, 4:40 PMShawn
04/25/2020, 4:42 PMOrdering
enum and adding an extension function that returns it?Shawn
04/25/2020, 4:43 PMwhen
looks more idiomatic, is more flexible, and avoids having to call a function with three lambdas lol
enum class Ordering {
Greater, Less, Equal
}
fun <T : Comparable<T>> T.compareMatch(other: T): Ordering = when (compareTo(other)) {
1 -> Ordering.Greater
0 -> Ordering.Equal
else -> Ordering.Less
// or to be *absolutely* sure
// -1 -> Ordering.Less
// else -> throw IllegalStateException("compareTo returned out of spec value")
}
fun test(a: Int, b: Int) {
when (a.compareMatch(b)) {
Ordering.Greater -> println("greater!")
Ordering.Equal -> println("equal!")
Ordering.Less -> println("less!")
}
}
miha-x64
04/25/2020, 6:07 PMcompareTo
is free to return any int. Your example, fixed: Math.sign(compareTo(other))
Derek Peirce
04/25/2020, 6:29 PMwhen (a.compareTo(b)) {
> 0 -> ...
0 -> ...
< 0 -> ...
}
This would require adding >
and <
to allowed operations for when
cases, and knowing that these conditions are exhaustive, but it would work.Shawn
04/25/2020, 8:50 PMIt’s free; having an extra enum is not.oh no, a whole extra enum 😱😱
Your example, fixeduh thanks, don’t think
Math.sign()
is on the jvm, but we could just check if the value is greater or less than 0jw
04/26/2020, 12:25 AMsignum
and it's only for floating-point-based types.Shawn
04/26/2020, 12:25 AMDerek Peirce
04/26/2020, 12:33 AMInt.sign
(https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.math/sign.html), though it would be nice if the restricted return values of -1, 0, and 1 were part of the method's signature so that you could restrict a when
to those three values.miha-x64
04/26/2020, 9:10 AMoh no, a whole extra enum 😱😱well, yes, a whole extra class which must be loaded, verified and compiled. For example, some stdlib internals use
typealias ... = Int
and `const val`s as 'free enums'.jw
04/27/2020, 1:13 AMAstronaut4449
04/27/2020, 12:50 PMwhen {
a > b -> "greater"
a < b -> "less"
else -> "even"
}
I would prefer an enum over integers as comparison results. But having two concepts in the stdlib would be very confusing imho.
Another possibility could be to replace the comparator results with an enum/sealed class that magically inherits from Int
. But I guess that would need some compiler magic and deep feasability investigation and I don't think it's worth the effort.Cody Engel
04/27/2020, 7:05 PMAstronaut4449
04/27/2020, 7:17 PM