I'm struggling to write a method that operates on either Free Monad to Tagles Final. I would like to use type class to pass an interpreter that produces a Monad. In the same function I would like to use map
function.
I don't know how to express type bound so that the M type is a functor or monad.
import cats._
import cats.free.Free
def eval[M[_]](param: String)(implicit op: Algebra ~> M): M[String] {
val program: Free[Algebra, String] = Free.liftF(Operation(param))
Free.foldMap(op)
}
def process[M[_]](param: String)(implicit op: Algebra ~> M): M[String] {
val result = eval(param)
result.map(_.toUpper) //this doesn't compile because M is missing map method
}
Try
import cats.{Monad, ~>}
import cats.free.Free
import cats.syntax.functor._
import scala.language.higherKinds
trait Algebra[_]
case class Operation(str: String) extends Algebra[String]
def eval[M[_]: Monad](param: String)(implicit op: Algebra ~> M): M[String] = {
val program: Free[Algebra, String] = Free.liftF (Operation (param) )
Free.foldMap(op).apply(program)
}
def process[M[_]: Monad](param: String)(implicit op: Algebra ~> M): M[String] = {
val result = eval(param)
result.map(_.toUpperCase)
}