PoisonedYouth
05/27/2023, 11:29 AMEither
.
What is the correct way to use Either
in combination with an init-Block of an data class?
data classUser (
val id: Identity,
val firstName: String,
val lastName: String,
val birthDate: LocalDate,
val address: Address,
) {
init {
require(firstName.isNotEmpty()){
"FirstName must not be empty."
}
}
}
Is it the correct way to migrate the data class to a class with a private constructor and a builder function that returns an Either
?Ruslan Ustits
05/27/2023, 11:37 AMName
or NotBlankString
that will hold a notBlank requirement.
This class can have a factory method like this:
Name.from(str: String): Either<Blank, Name>
And User class then will look like:
data class User (
val id: Identity,
val firstName: Name, // here we are sure that Name is not blank
val lastName: String,
val birthDate: LocalDate,
val address: Address,
)
simon.vergauwen
05/27/2023, 12:07 PMRuslan Ustits
05/27/2023, 1:52 PMPoisonedYouth
05/27/2023, 2:21 PMsimon.vergauwen
05/27/2023, 3:35 PMEither
you can easily accumulate errors to figure out all the different things that went wrong to initialise your types.
Or you short-circuit, which is the same as require
but using ensure
and returning an Either
instead of throwing an exception.
You’re free to model it however you care about.Iliyan Germanov
05/27/2023, 4:30 PMsuspend
validations. @simon.vergauwen @Ruslan Ustits we might consider adding suspend from(value: A): Either
.
My take is that the earlier you validate your domain data, the earlier you'll have guarantees with your types. TL;DR;
• No Arrow Exact + primitive Int
• => you'll need to validate every single function that accepts Int
• With Arrow Exaxt and custom Quantity
=> you'll need to validate quantity only once and every function down the chain that accepts Quantity
won't do validation.
• Either
is powerful monad and when combined with Raise
you can do whatever you want
• +1 for Simon's and Ruslan's pointPoisonedYouth
05/27/2023, 6:48 PM