lets say I am using `Either`, and I have two param...
# arrow
u
lets say I am using
Either
, and I have two params called
due
and
standing
- both params are charges to the customer and the code that generates both returns
Either<Problem, Amount>
-- What is the most effective way to map the generic problems to each param ? The
Amount
domain object returns a generic
AmountProblem
, but I need
DueAmountProblem
and
StandingAmountProblem
for proper validation.
I am doing the below at the moment but it feels cumbersome:
sealed interface BillProblem: Problem {
data object DueAmountLessThanZero:   BillProblem
data object DueAmountIsNegative:          BillProblem
data object StandingChargeAmountLessThanZero: BillProblem
data object StandingChargeAmountIsNegative:        BillProblem
}
data class Bill(val due: Money, val standing: Money) {
companion object {
private fun createStandingAmount(
dto: Money
): EitherNel<Problem, Amount> =
Money.make(dto).mapLeft { problems ->
problems.map {
when (it) {
MoneyProblem.LessThanZero ->
BillProblem.StandingChargeAmountLessThanZero
MoneyProblem.IsNegative ->
BillProblem.StandingChargeAmountIsNegative
}
}
}
private fun createDueAmount(
dto: Money
): EitherNel<Problem, Amount> =
Money.make(dto).mapLeft { problems ->
problems.map {
when (it) {
MoneyProblem.LessThanZero ->
BillProblem.DueAmountLessThanZero
MoneyProblem.IsNegative        ->
BillProblem.DueAmountIsNegative
}
}
}
fun create(
bill: dto
): EitherNel<Problem, Bill> = either {
Bill(
due      = createDueAmount(dto.dueAmount).bind(),
standing = createStandingAmount(dto.standingAmount).bind()
)
}
}
}
p
something like
Copy code
private fun createAmount(dto: Money, lessThanZero: BillProblem, isNegative: BillProblem): EitherNel<BillProblem, Amount> =
    Money.make(dto).mapLeft { problems ->
        problems.map {
            when (it) {
                MoneyProblem.LessThanZero -> lessThanZero
                MoneyProblem.IsNegative -> isNegative
            }
        }
    }
    
fun create(
    bill: dto
): EitherNel<Problem, Bill> = either {
    Bill(
        due      = createAmount(dto.dueAmount, BillProblem.DueAmountLessThanZero, BillProblem.DueAmountIsNegative).bind(),
        standing = createStandingAmount(dto.standingAmount, BillProblem.StandingChargeAmountLessThanZero, BillProblem.StandingChargeAmountIsNegative).bind()
    )
}
1
or have a
data class LessThanZero(val amountType: AmountType): BillProblem
etc