kikulikov
kikulikov

Reputation: 2582

Chain State monads with Scala Cats

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?

Upvotes: 2

Views: 482

Answers (1)

user5772563
user5772563

Reputation:

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.

Upvotes: 0

Related Questions