Итак, текущая реализация использует твиттер Future
вместе с генерацией исключений, чтобы сигнализировать о недопустимом варианте использования вместе с for-comprehensions
, например:
def someMethod(a: ...): Future[X] = {
// do something
// if something goes wrong throw exception
throw new Exception("Certificate not issued")
}
// in some other method, where exceptions break the loop and exit
def someOtherMethod(a: ...): Future[Y] = {
for {
x <- someMethod(...)
y <- yetAnotherMethod(...) // which throws another exception
} yield y
}
Общая идея заключается в том, что когда что-то пойдет не так, будет выброшено исключение, которое приведет к выходу из блока for-comprehension
. Я хочу уйти от создания исключений. Один из способов решить эту проблему — вернуть Either[Error, X]
, а другой — ADT
, используя sealed trait
. Таким образом, вместо того, чтобы бросать Exception
, вы можете вернуть Left(Error)
или ADT
, например case object NoCertificate extends CertificateResponse
.
Вопрос: могу ли я сохранить существующие циклы for, если я заменю методы, которые в настоящее время имеют throw Exception
, на Either
или ADT
?
Для полноты, вот как я бы закодировал свои Either
и ADT
:
sealed trait Error
case object CertificateError extends Error
case object SomeOtherError extends Error
def someMethod(a: ...): Future[Either[Error, CertificateResponse]] = {
// returns Left(CertificateError) or Right(CertificateResponse)
}
OR
sealed trait CertificateResponse
case class Certificate(x509) extends CertificateResponse
case object NoCertificate extends CertificateResponse
def someMethod(a: ...): Future[CertificateResponse] = {
// returns NoCertificate or Certificate(X509)
}
будет ли какое-либо из этих альтернативных решений (для создания исключений и нарушения ссылочной прозрачности) работать с for-comprehensions
? Будет ли отрицательный ответ: Left()
или NoCertificate
автоматически выходить из блока for-comprehension
? Если нет, то как сделать так, чтобы я мог оставить блоки for-comprehension
как есть? Что-то похожее на cats EitherT's leftMap
?
Обратите внимание: мы не можем использовать cats
Monad Transformer, например EitherT
(у которого есть leftMap
, сигнализирующий об условиях выхода), так как это не одна из библиотек, которые мы используем в нашем стеке. Извини!
Спасибо!
EitherT
, можно ли использовать эту библиотеку? Потому что на самом деле поведение, которое вы указываете, точно дает вам использование монадного преобразователя, и если вы не можете использовать библиотеки, вам придется кодировать их вручную. - person Astrid   schedule 15.08.2019