2017-03-07 29 views
2

我正在學習Monad Transformers,我正在學習如何嵌套Monads。使用Monads變壓器堆疊Monads

所以我們可以說我想爲了這個造型我也

type Error = String 
type FutureEither = EitherT[Future, Error, A] 
type FutureEitherOption = OptionT[FutureEither, A] 

現在我做

val p1 = 1.pure[FutureEitherOption] 

,我得到

OptionT(EitherT(Future(Success(Right(Some(1)))))) 
到模型,以便創建一個 Future[Either[String, Option[A]]]

所以這看起來是正確的。我在一個選項內有一個1,它位於未來成功的內部。好!

但如果我這樣做

Option.empty[Int].pure[FutureEitherOption] 

我希望,我會得到Future(Success(Right(None)))但我看到輸出

OptionT(EitherT(Future(Success(Right(Some(None)))))) 

而且,如果我想是這樣

Future(Success(Left("fail"))) 

如果我嘗試做

val p2 = Left("fail").pure[FutureEitherOption] 

輸出是怪異

OptionT(EitherT(Future(Success(Right(Some(Left(fail))))))) 

,因爲現在有兩個Eithers這不是我的造型都....

回答

3

1Int等類型的通過調用.pure[FutureEitherOption]你得到正確的形狀:

OptionT(EitherT(Success(Right(Some(1))))) 

Option.empty[Int]是類型0的所以你需要做的:

OptionT[FutureEither, Int](Option.empty[Int].pure[FutureEither]) 

,以獲得正確的形狀:

OptionT(EitherT(Success(Right(None)))) 

Left("fail")Left[String, Nothing]類型的(但實際上也Either[Error, Option[Int]]),所以你需要做的:

OptionT[FutureEither, Int](EitherT[Future, Error, Option[Int]](Either.left[Error, Option[Int]]("fail").pure[Future])) 

,以獲得正確的形狀:

OptionT(EitherT(Success(Left(fail)))) 

然後你終於可以撰寫所有這些的。例如,你可以寫一個換理解爲:

for { 
    a <- 1.pure[FutureEitherOption] 
    b <- OptionT[FutureEither, Int](Option.empty[Int].pure[FutureEither]) 
    c <- OptionT[FutureEither, Int](EitherT[Future, Error, Option[Int]](Either.left[Error, Option[Int]]("fail").pure[Future])) 
} yield() 

注:我已明確標註的所有類型爲了讓您更好地瞭解它的事情。