Hey! I was wondering if it was possible to possibl...
# getting-started
t
Hey! I was wondering if it was possible to possibly use contracts to cast data as not null as long as the type does not equal Unit. I use
Unit
to represent when an action has been preformed but no data is returned, so if it's anything but unit then there's data in the class.
Copy code
sealed class Test<out T>(val success: Boolean) {
  abstract val data: T?

  class A<out T>(override val data: T?) : Test(true)
  class B<out T>(override val data: T?) : Test(false)
}

fun Test<Any>.isSuccess(): Boolean {
  contract {
    returns(true) implies(this@isSuccess is Test.A)
    // if T != Unit then data != null
  }
  return this is Test.A
}
y
I experimented a bit with this but it doesn't seem possible because you can't have a contract on anything that isn't a parameter of a method, even if that thing is a property of it. Splitting it into 2 methods could've worked if you could define a contract based on properties, but for now it ain't possible. However, I think your design can be massively improved in a way to allow this to work. Kotlin has the
Nothing?
Type whose only value is
null
, which makes it quite similar to
Unit
. What I'm thinking is, instead of having
Unit
represent an action that returns no data, have
Nothing?
represent such an action, and make it so that data is non-nullable. Also, you don't need a
val success
as a member property of
Test
, especially since you can make your
fun isSuccess
an extension val instead. Finally, data can be a non-abstract constructor property. All in all, here's what I'm thinking:
Copy code
sealed class Test<out T>(val data: T) {
  class A<out T>(data: T) : Test<T>(data)
  class B<out T>(data: T): Test<T>(data)
}
val <T> Test<T>.isSuccess(): Boolean {
  contract {
    returns(true) implies(this@isSuccess is Test.A)
  }
  return this is Test.A
}
 
fun functionWithNoData(): Test<Nothing?> {
  println("Nothing to see here, or is it Nothing? (Haha, get it?)")
  return Test.A(null)
}
fun answerToLife(isBinary: Boolean) = Test.A(if(isBinary) "000101010" else "42")