【问题标题】:Chain State monads with Scala Cats使用 Scala Cats 的链式状态单子
【发布时间】:2017-10-11 02:26:43
【问题描述】:

我正在尝试使用 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)

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

【问题讨论】:

  • 如果返回与给定相同的状态,为什么还需要状态单子?这些对我来说看起来很简单。
  • 除了 Cyrille 所说的之外,您的两个计算具有不同类型的状态,因此它们本身不兼容。您的示例看起来更像您有函数 f1: String =&gt; Seq[Stringf2: Seq[String] =&gt; Seq[String] 并且正在寻找组合 f1 andThen f2

标签: scala monads scala-cats


【解决方案1】:

注意你的类型:

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

函数flatMap 接受M[A]A =&gt; M[B] 的参数并返回M[B],但显然你的M[_] for Step1Step2 显然不同,即使它们都使用@ 987654332@ 数据类型。

请注意,State 的类型签名为 * -&gt; * -&gt; *,或者看起来类似于 State[S, A],其中您的 S 是您的“状态”,A 是您的值。

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

【讨论】:

  • 感谢您的详细说明!
猜你喜欢
  • 2019-12-24
  • 2022-01-22
  • 2018-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多