2017-06-04 27 views
0

我有一个用例,我需要用它来理解Scala中的ADT。我可以使用flatMaps编写相同的代码,但看起来有点难以理解。下面是一段代码。用于理解的ADT

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语句包含在for-comprehension中以实现相同。

在此先感谢。

回答

1

你可以把模式匹配和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") 

然后,您可以赶上在recover声明此故障,换补偿后。问题是,你想抓住三个不同的“错误”:事实上,没有更多的可用席位,事实fetchRecordByImdbAndScreenId可以返回MovieBookingInformationFetchError,事实updateSeatReservationByImdbAndScreenId可以返回MovieBookingUpdateFailed

除非您定义自定义异常,而不是自定义结果类型(并在之后恢复这些异常),否则您将无法在这三者之间进行分离,只能用于理解。

+0

谢谢@Cyrille Corpet!非常感激!我觉得我现在很好走...使用我在这种情况下使用的flatMap是否好,或者我应该去理解而不是?再次感谢 – boseAbhishek

+0

就我个人而言,我认为你应该总是使用理解,除非你想要做的是_map_或_flatMap_。只要将这些结合在一起,可能使用_filter_,从下一位读者的角度来看,就很难理解了。因此,在这种情况下,请使用理解。当然要记住,编译器的第一阶段会立即转换为map/flatMap/filter表达式 - 因此它们完全等价。 – Phasmid

+0

就我个人而言,我会写出你放在你的平面图中作为辅助函数的东西,然后去理解 –