带有 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[_]
对于 Step1
和 Step2
明显不同,即使它们都使用 State
数据类型。
请注意,State
的类型签名为 * -> * -> *
,或者它看起来像 State[S, A]
,其中您的 S
是您的 "state" 和 A
是你的价值。
在这种情况下,如果你真的想要 flatMap
两个不同的 State
那么你必须先 "adjust" 并将其中一个的 S
等同起来。
我正在尝试使用 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[_]
对于 Step1
和 Step2
明显不同,即使它们都使用 State
数据类型。
请注意,State
的类型签名为 * -> * -> *
,或者它看起来像 State[S, A]
,其中您的 S
是您的 "state" 和 A
是你的价值。
在这种情况下,如果你真的想要 flatMap
两个不同的 State
那么你必须先 "adjust" 并将其中一个的 S
等同起来。