了解 Scala 中的 monad 转换器
Understanding monad transformers in Scala
我正在尝试了解如何使用 Monad 变形金刚。我阅读了有关它的 wiki article,但仍有一些问题。
我们有 IO
个 monad 需要读取用户的输入。但并不总是提供输入。所以是Option
。为了简化我们可以定义一个 monad OptionT
which "incapsulates" action of IO
monad。
在我的特殊情况下,我有两个类型为 Future[Option[String]]
和 Future[List[Int]]
的单子。这意味着要简化它我需要两个不同的转换器 ListT[T]
和 OptionT[T]
分别用于每个 monad 类型,我在其中嵌入 Future
行为......对吗?
是的,monad 转换器的工作方式是帮助您处理 "inner" monad,该 "transformed" 被 "outer" monad。
所以 F[Option[A]
可以变成 OptionT[F, A]
(其中 F
是任何 monad),这样更容易使用。
关于ListT
,可能没那么容易。例如 cats
没有提供,请参阅 their FAQ 了解更多信息。正如他们所建议的那样,您可以使用 Nested
代替不需要 flatMap
的情况,例如:
import cats._
import cats.implicits._
import cats.data.Nested
import scala.concurrent.Future
import scala.concurrent.Implicits.global
val futList = Future(List(1, 2, 3))
Nested(futList).map(_ + 1).value // Future(List(2, 3, 4))
如果你想要另一个 monad 转换器,这里是我写的一篇短文:https://blog.buildo.io/monad-transformers-for-the-working-programmer-aa7e981190e7
我正在尝试了解如何使用 Monad 变形金刚。我阅读了有关它的 wiki article,但仍有一些问题。
我们有 IO
个 monad 需要读取用户的输入。但并不总是提供输入。所以是Option
。为了简化我们可以定义一个 monad OptionT
which "incapsulates" action of IO
monad。
在我的特殊情况下,我有两个类型为 Future[Option[String]]
和 Future[List[Int]]
的单子。这意味着要简化它我需要两个不同的转换器 ListT[T]
和 OptionT[T]
分别用于每个 monad 类型,我在其中嵌入 Future
行为......对吗?
是的,monad 转换器的工作方式是帮助您处理 "inner" monad,该 "transformed" 被 "outer" monad。
所以 F[Option[A]
可以变成 OptionT[F, A]
(其中 F
是任何 monad),这样更容易使用。
关于ListT
,可能没那么容易。例如 cats
没有提供,请参阅 their FAQ 了解更多信息。正如他们所建议的那样,您可以使用 Nested
代替不需要 flatMap
的情况,例如:
import cats._
import cats.implicits._
import cats.data.Nested
import scala.concurrent.Future
import scala.concurrent.Implicits.global
val futList = Future(List(1, 2, 3))
Nested(futList).map(_ + 1).value // Future(List(2, 3, 4))
如果你想要另一个 monad 转换器,这里是我写的一篇短文:https://blog.buildo.io/monad-transformers-for-the-working-programmer-aa7e981190e7