带有 Scala Cats 的 Chain State monad

Chain State monads with Scala Cats

我正在尝试使用 Scala 和 Cats 以函数式方式链接一些顺序操作。它们单独看起来很完美,但我不确定现在如何用 flatMap / 链接它们以进行理解。

所以,比方说,我有类似

的东西
import cats.data.State

object Step1 {
    def apply() = State[String, Seq[String]] { text =>
        val ans = text.trim.split("""[\s]+""").toSeq
        (text, ans)
    }
}

println(Step1().run("Lorem Ipsum Dolor").value)

object Step2 {
    def apply() = State[Seq[String], Seq[String]] { terms =>
        val ans = terms.map(_.toLowerCase)
        (terms, ans)
    }
}

println(Step2().run(Seq("Lorem", "Ipsum", "Dolor")).value)

理想情况下,我想要

for {
    a <- Step1()
    b <- Step2()
} yield (b)

实现此目标的最佳方法是什么?

记下你的类型:

对于你的 Step1,你有 State[String, Seq[String]]。 对于你的 Step2,你有 State[Seq[String], Seq[String]].

函数 flatMap 接受 M[A]A => M[B] 和 returns M[B] 的参数,但很明显你的 M[_] 对于 Step1Step2 明显不同,即使它们都使用 State 数据类型。

请注意,State 的类型签名为 * -> * -> *,或者它看起来像 State[S, A],其中您的 S 是您的 "state" 和 A 是你的价值。

在这种情况下,如果你真的想要 flatMap 两个不同的 State 那么你必须先 "adjust" 并将其中一个的 S 等同起来。