2017-11-21 19 views
2

素敵なモナティブな方法で一連の非同期プロセスを作成する方法に苦労しています。プロセスの各ステップが失敗し、Future[Either[String, T]]が取得されている可能性があります。理解のために未来といえども

def firstStep(input: Int): Future[Either[String, Long]] = ??? 
def secondStep(input: Long): Future[Either[String, String]] = ??? 
def thirdStep(input: String): Future[Either[String, Double]] = ??? 

は、私はこの

def process(input: Int): Future[Either[String Double]] = { 
    for{ 
     res1 <- firstStep(input) 
     res2 <- secondStep(res1) 
     res3 <- thirdStep(res2) 
    } yield res3 
} 

のようにそれらを構成したいと考え、これらの関数を考える。しかし、各部分的な結果がEither[String, T]あるので、これは動作しません、と私は必要なのT自身である(あるいは単にその場合は実行を停止してLeftを返します)。

どのように私は良いモナドの方法で(for-comprehensionsを使用して)この関数を構成できますか?

答えて

3

EitherTモナド変換子は猫やscalazから(しゃれが意図した)のいずれか、助けることができる:

import cats._ 
import cats.implicits._ 
import cats.EitherT 

def process(input: Int): Future[Either[String, Double]] = { 
    val res = for { 
     res1 <- EitherT(firstStep(input)) 
     res2 <- EitherT(secondStep(res1)) 
     res3 <- EitherT(thirdStep(res2)) 
    } yield res3 
    res.value 
} 
+0

おかげで、一つの質問は、先物の上に、ブロッキングのいずれかの種類を実行し、このソリューションのですか? – Mikel

+1

@Mikelいいえ、これらの呼び出しはすべて 'EitherT'の' flatMap'と 'map'呼び出しです。 –

関連する問題