简体   繁体   中英

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?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM