arrow-analysis icon indicating copy to clipboard operation
arrow-analysis copied to clipboard

Conversion from base types

Open serras opened this issue 3 years ago • 3 comments

(From a conversation on Slack)

The idea is to automatically provide conversions or constructors from basic types to classes with invariants.Some ideas:

  • For value class we create from the base type to the type with invariants, as in the case above. Maybe we should return String? instead.
@JvmInline
value class String5(val value: String) {
    init {
        require(value.length < 5)
    }
}

fun String.asString5() = if (this.length < 5) {
    String5(this).right()
} else {
    "String '$this' should be smaller than 5".left()
}
  • Conversely, we could add pseudo-constructors in the companion object which return the type but nullable.
@JvmInline
value class String5(val value: String) {
    init {
        require(value.length < 5)
    }

    companion object {
        fun attempt(value: String): String5? = ...
    }
}

serras avatar Apr 06 '22 19:04 serras

My current preference is to do (1), since we can do it without requiring an empty companion object (as happens with the lenses plug-in). However, I see the benefit of providing a generic way to say "I don't know whether all the invariants are satisfied here, so please return a nullable".

Any other ideas, @raulraja @nomisRev?

serras avatar Apr 06 '22 19:04 serras

This method in the previous refined types plugin used to be based on nullable too. I think nullable is better so we don't impose a dependency on arrow core or have to provide a custom validation class, also don't allocate just to validate. Alternatively, we could have the plugin automatically codegen versions for Either or ValidatedNel if we find arrow.core is in the user classpath.

I also prefer the first option so we don't have to provide a companion.

raulraja avatar Apr 06 '22 20:04 raulraja

I also prefer the first option so we don't have to provide a companion.

I've never wanted this for Arrow Optics, but there is still no way to currently do this unless you're a compiler plugin. KSP cannot add a companion either but Arrow Analysis should be able to do this since it can add it, right? KotlinX Serialization also adds a companion object on the fly if it's not present.

I think nullable is better so we don't impose a dependency on arrow core

100% agreed.

nomisRev avatar Apr 07 '22 07:04 nomisRev