2015-07-12 8 views
4

Учитывая Option[Future[Option[Int]]]:Опция [Future [Опция [Int]]] => Future [Опция [Int]]

scala> val x: Option[Future[Option[Int]]] = Some (Future (Some (10))) 
x: Option[scala.concurrent.Future[Option[Int]]] = 
    Some([email protected]) 

Я хочу Future[Option[Int]].

Я матч шаблон (или использовать Option#getOrElse):

scala> x match { 
    | case Some(f) => f 
    | case None => Future { None } 
    | } 
res6: scala.concurrent.Future[Option[Int]] = 
    [email protected] 

scala> res6.value 
res7: Option[scala.util.Try[Option[Int]]] = Some(Success(Some(10))) 

Но, есть функция высшего порядка, который будет делать эту работу?

Я думал использовать sequence, но не имеют внешний вид List:

> :t sequence 
sequence :: Monad m => [m a] -> m [a] 
+0

Если вы просто очищаете внешний слой, почему бы просто не использовать 'x.getOrElse (Future {None})'? – jwvh

+0

FYI 'Future.successful (None)' - небольшая оптимизация над 'Future {None}' в этом случае. – Ryan

+0

Что означает «небольшая оптимизация»? С идиоматической точки зрения Scala? –

ответ

6

Хаскеля sequence не столь общим, как это может быть, или как родовое, как Scalaz (и я м, предполагая, что у вас все в порядке с решением Scalaz, так как вы упомянули sequence).

Scalaz-х sequence (и Хаскель sequenceA в Data.Traversable) только требует, чтобы конструктор внешнего вида имеет Traverse экземпляра не обязательно должен быть списком. Option имеет Traverse экземпляр, так sequence будет прекрасно работать здесь:

import scala.concurrent.ExecutionContext.Implicits.global 
import scala.concurrent.Future 
import scalaz._, Scalaz._ 

def collapse(x: Option[Future[Option[Int]]]): Future[Option[Int]] = 
    x.sequence.map(_.flatten) 

Scalaz также предоставляет метод orZero расширения для Option, который позволил бы просто написать x.orZero, так как нуль Future[Option[Int]] является Future(None).

Я бы на самом деле, вероятно, использовал x.getOrElse(Future.successful(None)), хотя в этом случае он немного (возможно, не имеет отношения к делу) более результативен, но, что более важно, он столь же четкий и почти такой же краткий, как и параметры Scalaz.

Смежные вопросы