使用 Monads Transformer 堆叠 Monads
Stacking Monads using Monads Transformers
我正在学习 Monad Transformers,我正在尝试学习如何嵌套 Monad。
假设我想创建一个 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 里面有一个 1,它在一个 Right 里面,它在一个 Future Success 里面。好!
但如果我这样做
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
是 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]))
为了获得正确的形状:
OptionT(EitherT(Success(Left(fail))))
然后你终于可以编写所有这些了。例如,您可以将 for-comprehension 写为:
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 ()
注意:我已经明确注释了所有类型,以便您更好地理解它是怎么回事。
我正在学习 Monad Transformers,我正在尝试学习如何嵌套 Monad。
假设我想创建一个 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 里面有一个 1,它在一个 Right 里面,它在一个 Future Success 里面。好!
但如果我这样做
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
是 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]))
为了获得正确的形状:
OptionT(EitherT(Success(Left(fail))))
然后你终于可以编写所有这些了。例如,您可以将 for-comprehension 写为:
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 ()
注意:我已经明确注释了所有类型,以便您更好地理解它是怎么回事。