如何表达强制类型参数表现得像仿函数的类型绑定

How to express type bound that forces the type param to behave like functor

我正在努力编写一种在 Free Monad 和 Tagles Final 上运行的方法。我想使用 type class 来传递生成 Monad 的解释器。在同一个函数中,我想使用 map 函数。

我不知道如何表达类型绑定,以便 M 类型是仿函数或 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
}

尝试

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)
}