我正在学习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 ....
答案 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))))
注意:我已明确注释所有类型,以便让您更好地了解它的作用。