ADT with for comprehension



我有一个用例,我需要在 Scala 中使用 ADT 进行理解。我可以使用flatMaps编写相同的代码,但似乎有点不可读。下面是一段代码。

case class MovieRecord(movie: Movie,
screenId: String,
availableSeats: Int,
reservedSeats: Option[Int] = None) {
def movieInfo = new MovieInfoResponse(movie.imdbId, screenId, movie.title, availableSeats, reservedSeats.getOrElse(0))
}

sealed trait MovieBookingInformation
case class MovieBookingInformationFetched(bookMovie: MovieRecord) extends MovieBookingInformation
case object MovieBookingInformationFetchError extends MovieBookingInformation

def modifyBooking(reserveMovie: MovieSelected): Future[String] = {
fetchRecordByImdbAndScreenId(reserveMovie.imdbId, reserveMovie.screenId) flatMap {
case MovieBookingInformationFetched(m) if (m.availableSeats > 0) =>
updateSeatReservationByImdbAndScreenId(m.copy(availableSeats = m.availableSeats - 1, reservedSeats = Some(m.reservedSeats.getOrElse(0) + 1))) flatMap {
case MovieBookingUpdated(updatedMovieBooking) =>
Future.successful(s"One seat reserved at Screen - ${updatedMovieBooking.screenId}")
case MovieBookingUpdateFailed =>
Future.successful(s"Movie seat reservation failed at screen ${reserveMovie.screenId}")
}
case MovieBookingInformationFetched(m) =>
Future.successful(s"Sorry! No more seats available for ${m.movie.title} at Screen - ${m.screenId}")
case MovieBookingInformationFetchError => Future.successful(s"No movie with IMDB ID ${reserveMovie.imdbId} found at ${reserveMovie.screenId}")
}
}

在上面的代码中,下一个方法对结果 ADT 内容和 if 语句的结果调用。我如何在理解中包含 if 语句以实现相同的目的。

提前谢谢。

您可以将模式匹配和if语句放在一个中以便理解Future

for {
MovieBookingInformationFetched(m) <- future1
if m.availableSeats > 0
MovieBookingUpdated(updatedMovieBooking) <- future2(m)
} yield updatedMovieBooking

但是,这将转换为Future.filter,因此,如果不满足谓词,或者模式无法匹配,则最终会得到

Future.failed(new NoSuchElementException("Future.filter predicate was not satisfied")

然后,您可以在 for-comp 之后的recover语句中捕获此故障。问题是您想捕获三个不同的"错误":没有更多可用席位的事实,fetchRecordByImdbAndScreenId可以返回MovieBookingInformationFetchError的事实,以及updateSeatReservationByImdbAndScreenId可以返回MovieBookingUpdateFailed的事实。

除非定义自定义异常而不是自定义结果类型(并在之后恢复这些异常),否则无法仅出于理解目的在这三者之间解离。

最新更新