使用Monads变形金刚堆叠Monads

时间:2017-03-07 04:25:12

标签: scala scala-cats

我正在学习Monad变形金刚,我正在努力学习如何筑巢Monads。

所以,让我们说我要创建一个Future[Either[String, Option[A]]]

所以为了模仿这个形状,我做了

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))))))

所以这看起来是正确的。我有一个选项内部的一个在一个权利内部,这是一个未来成功的内部。好!

但如果我这样做

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 ....

1 个答案:

答案 0 :(得分:3)

<?php $upcoming_news = $this->mastermodel->get_upcoimg_news(); ?> <div class="example1" id="example1"> <ul <?php if($this->lang->lang()=='ar') { ?> dir="RTL" <?php } ?>> <?php foreach ($upcoming_news as $row) { if ($this->lang->lang() == 'ar') $news = $row['news_description_ar']; else $news = $row['news_description_en']; ?> <li <?php if($this->lang->lang()=='ar') { ?> dir="RTL" style="text-align:right" <?php } ?>> <?= $news; ?> <br /> </li> <?php } ?> </ul> </div>属于1类型,因此通过调用Int可以获得正确的形状:

.pure[FutureEitherOption]

OptionT(EitherT(Success(Right(Some(1))))) 的类型为Option.empty[Int],因此您需要执行以下操作:

Option[Int]

为了获得正确的形状:

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]))

然后你最终可以组成所有这些。例如,您可以将for-comprehension写成:

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

注意:我已明确注释所有类型,以便让您更好地了解它的作用。