
Enforces exactness in data structures by leveraging the type system and smart constructors, ensuring values meet specified conditions. Supports composition and reuse of validation logic.
Module Arrow Exact
Arrow Exact allows you to use Kotlin's type system to enforce exactness of data structures.
Exact allows automatically projecting smart-constructors on a Companion Object. We can for
example easily create a NotBlankString type that is a String that is not blank, leveraging
the Arrow's Raise DSL to ensure the value is not blank.
import arrow.core.raise.Raise
import arrow.exact.Exact
import arrow.exact.ExactError
import arrow.exact.ensure
import kotlin.jvm.JvmInline
@JvmInline
value class NotBlankString private constructor(val value: String) {
companion object : Exact<String, NotBlankString> {
override fun Raise<ExactError>.spec(raw: String): NotBlankString {
ensure(raw.isNotBlank())
return NotBlankString(raw)
}
}
}We can then easily create values of NotBlankString from a String, which returns us a
Either with the ExactError or the NotBlankString. We can also use fromOrNull to get a
nullable value, or fromOrThrow to throw an ExactException.
note: Make sure to define your constructor as private to prevent creating invalid values.
fun example() {
println(NotBlankString.from("Hello"))
println(NotBlankString.from(""))
}The output of the above program is:
Either.Right(NotBlankString(value=Hello))
Either.Left(ExactError(message=Failed condition.))
You can also define Exact by using Kotlin delegation.
@JvmInline
value class NotBlankString private constructor(val value: String) {
companion object : Exact<String, NotBlankString> by Exact({
ensure(it.isNotBlank())
NotBlankString(it)
})
}You can define a second type NotBlankTrimmedString that is a NotBlankString that is also
trimmed. ensureExact allows us to compose Exact instances and easily
reuse the NotBlankString type.
@JvmInline
value class NotBlankTrimmedString private constructor(val value: String) {
companion object : Exact<String, NotBlankTrimmedString> {
override fun Raise<ExactError>.spec(raw: String): NotBlankTrimmedString {
ensure(raw, NotBlankString)
return NotBlankTrimmedString(raw.trim())
}
}
}Module Arrow Exact
Arrow Exact allows you to use Kotlin's type system to enforce exactness of data structures.
Exact allows automatically projecting smart-constructors on a Companion Object. We can for
example easily create a NotBlankString type that is a String that is not blank, leveraging
the Arrow's Raise DSL to ensure the value is not blank.
import arrow.core.raise.Raise
import arrow.exact.Exact
import arrow.exact.ExactError
import arrow.exact.ensure
import kotlin.jvm.JvmInline
@JvmInline
value class NotBlankString private constructor(val value: String) {
companion object : Exact<String, NotBlankString> {
override fun Raise<ExactError>.spec(raw: String): NotBlankString {
ensure(raw.isNotBlank())
return NotBlankString(raw)
}
}
}We can then easily create values of NotBlankString from a String, which returns us a
Either with the ExactError or the NotBlankString. We can also use fromOrNull to get a
nullable value, or fromOrThrow to throw an ExactException.
note: Make sure to define your constructor as private to prevent creating invalid values.
fun example() {
println(NotBlankString.from("Hello"))
println(NotBlankString.from(""))
}The output of the above program is:
Either.Right(NotBlankString(value=Hello))
Either.Left(ExactError(message=Failed condition.))
You can also define Exact by using Kotlin delegation.
@JvmInline
value class NotBlankString private constructor(val value: String) {
companion object : Exact<String, NotBlankString> by Exact({
ensure(it.isNotBlank())
NotBlankString(it)
})
}You can define a second type NotBlankTrimmedString that is a NotBlankString that is also
trimmed. ensureExact allows us to compose Exact instances and easily
reuse the NotBlankString type.
@JvmInline
value class NotBlankTrimmedString private constructor(val value: String) {
companion object : Exact<String, NotBlankTrimmedString> {
override fun Raise<ExactError>.spec(raw: String): NotBlankTrimmedString {
ensure(raw, NotBlankString)
return NotBlankTrimmedString(raw.trim())
}
}
}