使 F[_] 在接受 IO 时实现 Monad 特性

Make F[_] implementing Monad trait while accepting IO

假设我们有代码(<: 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 class 内):

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]]

如何解决或以不同的方式实现?

替换

class External[F[_] <: Monad[F] : Concurrent]

class External[F[_]: Monad : Concurrent]

成为 Monad 并不意味着成为 Monad 的子类型。这意味着当前类型有一个 class Monad 类型的实例。

与 OOP 相反,在 FP 中实现一些抽象行为不是通过 extending/inheritance/subtype 多态性而是通过 implicits/defining type-class instances/ad hoc 多态性.

也许您需要导入必要的语法:

import cats.syntax.flatMap._

import cats.syntax.functor._

或一次所有语法

import cats.syntax.all._

https://eed3si9n.com/herding-cats/import-guide.html