2016-08-10 10 views
2

Как объединить Future[A] и Future[Option[A]] в одном for -познании? Следующий фрагмент работает, но выглядит уродливым, есть ли лучший способ?Сочетание различных вложенных монад в понимании

def getOne: Future[Int] = Future.value(1) 

    def getSomeOne: Future[Option[Int]] = Future.value(Some(1)) 

    def main(args: Array[String]): Unit = { 
    val sum = for { 
     y <- OptionT(getOne.map(Some(_)).asInstanceOf[Future[Option[Int]]]) 
     x <- OptionT(getSomeOne) 
    } yield x + y 

    println(Await.result { sum.run }) 
    } 
+0

какое будущее вы используете? Я не могу найти значение метода в 'scala.concurrent.Future'. – pedrofurla

+0

'twitter.util.Guture'. Не имеет значения, так часто бывают случаи для «Functor» и «Monad» – synapse

+0

Не беспокойтесь, работайте вокруг него. – pedrofurla

ответ

1

OptionT(getOne.map(Option(_)) работает для меня без кастингов. Проблема с вашим кодом заключается в том, что тип Some равен Some не вариант.

Использования будущего Скала:

scala> :paste 
(for { 
    y <- OptionT(getOne.map(Option(_))) 
    x <- OptionT(getSomeOne) 
} yield x + y).run 
res14: scala.concurrent.Future[Option[Int]] = List() 

scala> Await.result(res14, duration.Duration.Inf) 
res16: Option[Int] = Some(2) 

(не знает, почему это список печати() для неисполненного будущего, может быть РЕПЛА вещь?)

+0

'point [Option]' работает также. Но оказывается, что для всего сложного понимания недостаточно сделать все для опции «OptionT». – synapse

+0

'Some.type' был неправильным, это был бы тип сопутствующего объекта. – pedrofurla

+0

Я думаю, что немного лучше использовать предоставленные лифты для этого. 'y <- OptionT.optionTMonadTrans.liftM (getOne)' –