链斯卡拉期货返回类型
我想链接在斯卡拉期货,但它给了我错误的返回类型。链斯卡拉期货返回类型
我有以下几种方法:
def getOneRecordByModel(x:DirectFlight): Future[Option[FlightByDetailModel]] = {
select.allowFiltering().where(_.from eqs x.from).and(_.to eqs x.to).and(_.departure eqs x.departure).and(_.arrival eqs x.arrival).and(_.carrier eqs x.airline).and(_.code eqs x.flightCode).one()
}
def getRecordByUUID(x:FlightByDetailModel): Future[Option[FlightByUUIDModel]] = {
select.allowFiltering().where(_.uuid eqs x.uuid).one()
}
def getUUIDRecordByModel(x:DirectFlight): Future[Option[FlightByUUIDModel]] = {
getOneRecordByModel(x) andThen {
case Success(Some(flight)) => getRecordByUUID(flight)
case Success(x) => Success(x)
case Failure(x) => Failure(x)
}
}
但现在我得到的错误是,getUUIDRecordByModel
返回类型为Future[Option[FlightByDetailModel]]
如何正确地把它们连?
我会用flatMap
来代替。
def getUUIDRecordByModel(x:DirectFlight): Future[Option[FlightByUUIDModel]] = {
getOneRecordByModel(x) flatMap {
case Some(flight) => getRecordByUUID(flight)
case None => Future.successful(None)
}
}
andThen
施加副作用的函数,并返回原来Future
,而不是内之一。
就是这样。非常感谢你! – elmalto 2014-09-04 20:32:18
你可以用scalaz monad变形器,optionT更好地做到这一点。您可以芦苇组漂亮的文章,更具体的,你需要这一个:http://eed3si9n.com/learning-scalaz/Monad+transformers.html#Monad+transformers
这一个是很好的:http://noelwelsh.com/programming/2013/12/20/scalaz-monad-transformers/
def getOneRecordByModel(x:DirectFlight): Future[Option[FlightByDetailModel]] = ???
def getRecordByUUID(x:FlightByDetailModel): Future[Option[FlightByUUIDModel]] = ???
def getUUIDRecordByModel(x:DirectFlight): Future[Option[FlightByUUIDModel]] = {
import scalaz.OptionT._
val flightByUUID = for {
flightByDetailModel <- optionT(getOneRecordByModel(x))
flightByUUIDModel <- optionT(getRecordByUUID(flightByDetailModel))
} yield flightByUUIDModel
flightByUUID.run
}
为了能够使用optionT与scala.concurrent.Future你需要函子和单子实例是在范围
import scala.concurrent.Future
object FutureMonadAndFunctor {
import scalaz.Monad
implicit def FutureM(implicit ec: ExecutionContext): Monad[Future] = new Monad[Future] {
def point[A](a: => A): Future[A] = Future(a)
def bind[A, B](fa: Future[A])(f: (A) => Future[B]): Future[B] = fa flatMap f
}
implicit def FutureF(implicit ec: ExecutionContext): Functor[Future] = new Functor[Future]{
def map[A, B](fa: Future[A])(f: (A) => B): Future[B] = fa map f
}
}
import scala.concurrent.ExecutionContext.Implicits.global
implicit val F = FutureMonadAndFunctor.FutureF
implicit val M = FutureMonadAndFunctor.FutureM
谢谢你的洞察力。我已经多次遇到斯卡拉兹了。我想是我该做一些学习的时候了。 – elmalto 2014-09-04 20:35:27
一个简单的解决方案是使用用于flatMap组合物代替andThen,这是相当专用于处理副作用:
getOneRecordByModel(x) flatMap {
...
}
为了与期货合作,我发现多次阅读this page很有帮助。
该解决方案和上面的2实际上是相同的。他们提出了flatMaps组成的简单答案。这对于一次性解决方案很有用。
for {
oUuid <- getOneRecordByModel(x)
oFlight <- oUuid.map(getRecordByUUID).getOrElse(Future.successful(None))
} yield oFlight
我怀疑给定的方法签名,你将会使用这个策略很多。如果是这样的话,建议@Eugene Zhulenev的回答如上(这是一个功能更强大的解决方案)。以为单子变压器可以看看乍一看有点吓人,代码这里的块:当你开始增加复杂性
val flightByUUID = for {
flightByDetailModel <- optionT(getOneRecordByModel(x))
flightByUUIDModel <- optionT(getRecordByUUID(flightByDetailModel))
} yield flightByUUIDModel
flightByUUID.run // this line grabs you a Future[Option[T]]
是非常简单的,可扩展的。希望这可以帮助你。
的作品以及非常感谢你。不幸的是,我只能选择一个正确的答案。 – elmalto 2014-09-04 20:33:39
当你使用和然后你不改变返回类型。你想要flatMap或map取决于另一种方法的返回类型。 – monkjack 2014-09-04 19:31:44
'和Then' combinator纯粹是为了副作用。它始终返回它未被调用的“未来”,保持不变。正如其他人所说,“map”和/或“flatMap”应该是你正在寻找的。 – cmbaxter 2014-09-04 19:46:50