scala - 使用cats.effect时,值flatMap不是类型参数F[Long]的成员

标签 scala scala-cats cats-effect

这可能以前被问过很多次,但我没有找到任何帮助。

我有一个简单的 Scala 代码,它生成取决于一些副作用的长数字。我将东西包装在一个 IO monad 中,但根据最小功率原则,我实际上将我的函数声明为 F[_]: Effect .现在代码无法编译,我不明白为什么,请提出可能有问题的地方

import cats.effect.{Clock, Effect}
import cats.syntax.all._
import java.util.concurrent.TimeUnit


...

  def generateId[F[_]: Effect](rid: Long)(implicit F: Effect[F], clock: Clock[F]): F[Long] =
    for {
      currentTimeNanos <- clock.realTime(TimeUnit.NANOSECONDS)
      tid              <- F.delay(Thread.currentThread().getId)
    } yield
      (tid << 40 /*    */ & 0xFFFFFF0000000000L) |
        (rid << 16 /*  */ & 0x000000FFFFFF0000L) |
        (currentTimeNanos & 0x000000000000FFFFL)

[error] /.../package.scala:34:41: value flatMap is not a member of type parameter F[Long]
[error]       currentTimeNanos <- clock.realTime(TimeUnit.NANOSECONDS)
[error]                                         ^
[error] /.../package.scala:35:34: value map is not a member of type parameter F[Long]
[error]       tid              <- F.delay(Thread.currentThread().getId)


另外,如果您对改进代码有任何建议,请告诉我。

最佳答案

问题是 F[_]: Effect 中的上下文绑定(bind)deugars 成一个隐式参数,所以编译器看到的是这样的:

def generateId[F[_]](rid: Long)(implicit ev: Effect[F], F: Effect[F], ...): F[Long] = ...

这意味着每次尝试解析隐式 Effect[F]在方法的主体中,它会失败,因为它认为显式 F而这个合成的ev是模棱两可的。

解决方案是删除上下文绑定(bind)或显式隐式 F: Effect[F]范围。我建议取消上下文绑定(bind),因为 Scala 允许您将两者结合起来是很容易犯这种错误的部分原因(在我看来,这是语言设计者的严重误判,因为我已经 said many times before )。

关于scala - 使用cats.effect时,值flatMap不是类型参数F[Long]的成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54740481/

相关文章:

Scala Cats 或 Scalaz 类型类 scanLeft 等

scala - Doobie - 将任意效果提升到 ConnectionIO 中

scala - 猫效应——独立效应的平行组合

scala - 对象可以从特征推断被覆盖的字段的类型吗?

list - 使用 Scala 创建一个列表,其中包含从 0 到 count – 1 的方 block 作为包含重复项的列表

scala - 在 sbt 中,如何与一个版本中不需要的依赖项交叉构建?

Scala,猫, `ap` 的用法

scala - Scala 是否支持类型构造函数的部分应用?

scala 猫模棱两可的隐含值

scala - 为什么是 "avoid method overloading"?