itbhp
01/11/2022, 5:26 PMkotlin.NoWhenBranchMatchedException: null
at arrow.core.computations.EitherEffect$DefaultImpls.bind(either.kt:20) ~[arrow-core-jvm-1.0.1.jar:?]
I am using the either monad comprehension block and the bind extension function but maybe I am missing something.
I am using arrow version 1.0.1
Basically I have few interface with suspended methods, and one interface exposing a method not suspended (and using jooq in the implementation to handle transactions)
interface Repository {
suspend fun getBy(userId: UserId): Either<Error, List<DomainObject>>
suspend fun update(obj: DomainObject) : Either<ErrorResult, Unit>
}
class TransactionMgmt(private val dslContext: DSLContext) {
fun <T> transaction(
block: () -> Either<Error, T>
): Either<ErrorResult, T> ...
interface Observer {
suspend fun onExpired(obj: DomainObject): Either<ErrorResult, Unit>
}
class ExpireUseCase(
private val repository: Repository,
private val transactionMgmt: TransactionMgmt,
private val observer: Observer
) : UseCase<Request, Response> {
override suspend fun execute(request: Request): Either<Error, Response> =
repository.getBy(request.userId)
.flatMap { obj ->
updateAndNotify(obj)
}
private suspend fun updateAndNotify(objs: List<DomainObject>): Either<Error, Response> {
return objs.fold(initial) { acc, obj ->
transactionMgmt.transaction {
runBlocking {
expire(obj, acc)
}
}
}
}
private suspend fun expire(
obj: DomainObject,
acc: Either<Error, Response>
): Either<Error, Response> = either {
val expiredObj = obj.copy(status = EXPIRED)
repository.update(expiredObj).bind()
observer.onExpired(expiredObj).bind()
Response(acc.bind().count + 1)
}
private val initial: Either<Error, Response> = Response(0).right()
}
Basically I am getting that error in the method
private suspend fun expire(
obj: DomainObject,
acc: Either<Error, Response>
): Either<Error, Response> = either {
val expiredObj = obj.copy(status = EXPIRED)
repository.update(expiredObj).bind()
observer.onExpired(expiredObj).bind()
Response(acc.bind().count + 1)
}
Sorry for the very long post, and maybe I am missing something really stupid but I cannot see it.
(this is a similar version of the actual code I am using, I cannot post the original one)itbhp
01/11/2022, 6:11 PMitbhp
01/11/2022, 6:21 PMitbhp
01/11/2022, 6:21 PMraulraja
01/12/2022, 8:31 AMnull
value where it would otherwise expect a typed value non nullable of Left
or Right
.
bind
is currently defined in the Either.bind
effect as an exaustive match over the Either data structure.
public suspend fun <B> Either<E, B>.bind(): B =
when (this) {
is Either.Right -> value
is Left -> control().shift(this@bind)
}
raulraja
01/12/2022, 8:32 AMthis
is null
and incorrectly typed it would not be able to match either of the two cases.raulraja
01/12/2022, 8:32 AMitbhp
01/12/2022, 8:38 AM