Hi, I just discover <contracts> and try to play wi...
# announcements
p
Hi, I just discover contracts and try to play with it and a functor. Can you confirm that, as is, there is no way to achieve the above logic ?
Copy code
data class ValueHolder<A> (val value: A){
	@OptIn(ExperimentalContracts::class)
	inline fun <reified B : A> valueIs(): Boolean {
		contract {
			returns(true) implies (this@ValueHolder is ValueHolder<B>) // <- compiler error here "Cannot check for instance of erased type: ValueHolder<B>"
		}
		return value is B
	}
}
the goal is to use
#valueIs
in a when statement and benefit of smart-casting in branch as
Copy code
when {
	valueHolder.valueIs<TypeA> -> doStuffWithAHolder(valueHolder)
	valueHolder.valueIs<TypeB> -> doStuffWithBHolder(valueHolder)
}
m
Shouldn't you also trip over the fact that experimental contracts need to be defined at the top level?
p
Do you mean that my function shouldn't be defined as a class member ? If so it seems possible according to this example and the fact my code compile if I replace
is ParsingContext<B>
with
is ParsingContext
(which is of no interest anymore)
m
oh nvm! They updated them in Kotlin 1.4
p
yeah, with the support of reified generic parameter 🙂
d
Even if
B
is reified,
ValueHolder
is still generic class, so all actual type parameters will be erased at runtime. So check
this is ValueHolder<B>
is equal to
this is ValueHolder<Any>
m
nvm
p
sure, but since the contracts API is for the compiler I thought it would be possible. At runtime I check the type of #value
d
This is question of contracts design, related to contracts verification. We will keep in mind this case when we'll work on contracts in future
p
thx for yours explanations
FYI I finally address the pb without using contracts :
Copy code
data class ValueHolder<A> (val value: A){
	@Suppress("UNCHECKED_CAST")
	fun <B : A> narrow() = this as ValueHolder<B>
}
Copy code
when (valueHolder.value) {
	is TypeA -> doStuffWithAHolder(valueHolder.narrow())
	is TypeB -> doStuffWithBHolder(valueHolder.narrow())
}
Thx to the powerfull type-inference of kotlin compiler :)
👍 1