raulraja
07/16/2018, 12:11 PMval result: Try<Unit> = Try { accessChecker.loggedInUserHasAccess() }.flatMap {
if (it) Try.just(Unit) else Try.raise(FeatureAccessDeniedException("No access for feature"))
}
val result: Try[Unit] = ForTry extensions {
bindingCatch {
val hasAccess = Try { accessChecker.loggedInUserHasAccess() }.bind()
if (hasAccess) just(Unit).bind()
else raiseError(FeatureAccessDeniedException("No access for feature")).bind()
}.fix()
}
or even better since this kind of modeling is not particular to Try
but to any data type that can perform error handling:
fun <F> MonadError<F>.checkAccess(): Kind<F, Unit> =
bindingCatch {
val hasAccess = catch { accessChecker.loggedInUserHasAccess() }.bind()
if (hasAccess) just(Unit).bind()
else raiseError(FeatureAccessDeniedException("No access for feature")).bind()
}
Try.monadError().checkAccess().fix() // Try<Unit>
Either.monadError<FeatureAccessDeniedException>().checkAccess().fix() // Either<FeatureAccessDeniedException, Unit>
IO.monadError().checkAccess().fix() // IO<Unit>
DeferredK.monadError().checkAccess().fix() // Deferred<Unit>
ObservableK.monadError().checkAccess().fix() // Observable<Unit>
...
This is all assuming loggedInUserHasAccess
may throw exceptions otherwise is simpler.