2017-06-04 203 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

就我個人而言,我會寫出你放在你的平面圖中作爲輔助函數的東西,然後去理解 –