I'm trying to chain a few sequential operations in a functional way with Scala and Cats. They look perfect separately but I'm not sure how can I chain them now with a flatMap / for comprehension.
So, let's say, I have something like
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)
Ideally, I'd like to have something like
for {
a <- Step1()
b <- Step2()
} yield (b)
What is the best way to achieve this?
Take note of your types:
For your Step1
, you have State[String, Seq[String]]
.
For your Step2
, you have State[Seq[String], Seq[String]]
.
The function flatMap
takes in an argument of M[A]
and A => M[B]
and returns M[B]
but clearly your M[_]
for Step1
and Step2
are clearly different even though they are both using the State
datatype.
Take note that State
has a type signature of * -> * -> *
or it looks something like State[S, A]
where your S
is your "state" and A
is your value.
In this case, if you really want to flatMap
the two distinct State
then you have to first "adjust" and equate the S
of one of them.