假设我们有代码(<: Monad[F]
不像预期的那样工作):
class External[F[_] <: Monad[F] : Concurrent](implicit proxy: Proxy[F]) { ... }
class Proxy[F[_] <: Monad[F]](implicit storage: Storage, async: Async[F]) {
def get(key: String): F[Option[Entry]] = {
async.blocking(storage.get(key))
}
}
我希望F[_]
是Monad
,因此proxy.get()
具有这些特征并启用例如(在External
类中):
proxy.get(key).flatMap(...)
到目前为止还好,但是当尝试用cats.effect.IO
实例化时,它不适用于External
:
implicit val proxy: Proxy[IO] = new Proxy()
implicit val external: External[IO] = new External()
有错误输出:
inferred type arguments [[+A]cats.effect.IO[A]] do not conform to value <local External>'s type parameter bounds [F[_] <: cats.Monad[F]]
如何以不同的方式解决或实现这一问题?
Replace
class External[F[_] <: Monad[F] : Concurrent]
class External[F[_]: Monad : Concurrent]
作为Monad
并不意味着是Monad
的子类型。这意味着存在当前类型的类型类Monad
的实例。
与OOP相反,在FP中实现一些抽象行为不是通过扩展/继承/子类型多态性实现的,而是通过隐式/定义类型类实例/特设多态性实现的。
也许你需要导入必要的语法:
import cats.syntax.flatMap._
或
import cats.syntax.functor._
或同时使用所有语法
import cats.syntax.all._
如何强制F[_]成为Monad的实例
https://eed3si9n.com/herding-cats/import-guide.html