Tôi có hai hàm trả về Tương lai. Tôi đang cố gắng để nuôi một kết quả sửa đổi từ chức năng đầu tiên vào khác bằng cách sử dụng một hiểu năng suất.Tương lai [Tùy chọn] trong Scala cho thấu hiểu
Cách tiếp cận này hoạt động:
val schoolFuture = for {
ud <- userStore.getUserDetails(user.userId)
sid = ud.right.toOption.flatMap(_.schoolId)
s <- schoolStore.getSchool(sid.get) if sid.isDefined
} yield s
Tuy nhiên tôi không hài lòng với việc có "nếu" trong đó, có vẻ như rằng tôi sẽ có thể sử dụng bản đồ để thay thế.
Nhưng khi tôi cố gắng với một bản đồ:
val schoolFuture: Future[Option[School]] = for {
ud <- userStore.getUserDetails(user.userId)
sid = ud.right.toOption.flatMap(_.schoolId)
s <- sid.map(schoolStore.getSchool(_))
} yield s
tôi nhận được một lỗi biên dịch:
[error] found : Option[scala.concurrent.Future[Option[School]]]
[error] required: scala.concurrent.Future[Option[School]]
[error] s <- sid.map(schoolStore.getSchool(_))
Tôi đã chơi xung quanh với một vài biến thể, nhưng đã không tìm thấy bất cứ điều gì hấp dẫn công trinh. Bất cứ ai có thể đề nghị một hiểu tốt hơn và/hoặc giải thích những gì sai với ví dụ thứ 2 của tôi?
Dưới đây là một ví dụ Runnable tối thiểu nhưng hoàn chỉnh với Scala 2.10:
import concurrent.{Future, Promise}
case class User(userId: Int)
case class UserDetails(userId: Int, schoolId: Option[Int])
case class School(schoolId: Int, name: String)
trait Error
class UserStore {
def getUserDetails(userId: Int): Future[Either[Error, UserDetails]] = Promise.successful(Right(UserDetails(1, Some(1)))).future
}
class SchoolStore {
def getSchool(schoolId: Int): Future[Option[School]] = Promise.successful(Option(School(1, "Big School"))).future
}
object Demo {
import concurrent.ExecutionContext.Implicits.global
val userStore = new UserStore
val schoolStore = new SchoolStore
val user = User(1)
val schoolFuture: Future[Option[School]] = for {
ud <- userStore.getUserDetails(user.userId)
sid = ud.right.toOption.flatMap(_.schoolId)
s <- sid.map(schoolStore.getSchool(_))
} yield s
}
Phải thừa nhận rằng scalaz làm tôi sợ một chút, tôi vẫn có một cách để đi trên đường cong học tập. Điều này giải quyết vấn đề cũng như tôi nghĩ rằng nó có thể được. Cảm ơn! – EvilRyry
Cảm ơn bạn đã trả lời, nhưng liên kết đến thư viện scalaz-contrib bị hỏng –
Bạn không cần 'scalaz-contrib nữa', vì các phiên bản tương lai của Monad hiện được cung cấp bởi scalaz bằng cách trộn đặc điểm' FutureInstances'. –