I'm trying to get my head around monads and Cats. Following some examples (e.g.cats) I wrote the code like below. But can't figure out how to make compiler
to do what I need and to compile, actually.
import cats.Id
import cats.free.Free
import cats.~>
object Filtering extends App {
sealed trait Filter[A]
case class WhitespaceFilter(text: String) extends Filter[Seq[String]]
case class LowerCaseFilter(strings: Seq[String]) extends Filter[Seq[String]]
def whitespaceFilter(text: String): Free[Filter, Seq[String]] = Free.liftF(WhitespaceFilter(text))
def lowerCaseFilter(strings: Seq[String]): Free[Filter, Seq[String]] = Free.liftF(LowerCaseFilter(strings))
val process: (String => Free[Filter, Seq[String]]) = {
text: String =>
for {
p1 <- whitespaceFilter(text)
p2 <- lowerCaseFilter(p1)
} yield p2
}
def compiler: Filter ~> Id =
new (Filter ~> Id) {
def apply[A](fa: Filter[A]): Id[A] =
fa match {
// The code doesn't compile if uncommented...
case WhitespaceFilter(text) => ??? // text.trim.split("""[\s]+""")
case LowerCaseFilter(terms) => ??? // terms.map(_.toLowerCase)
}
}
val result: Seq[String] = process("Some Text").foldMap(compiler)
println(result) // should be Seq("some", "text")
}
Thanks!