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

时间:2019-02-18 04:27:10

标签: scala scala-cats cats-effect

这可能是以前问过很多次的,但是我没有找到建议。

我有一个简单的Scala代码,该代码会生成长整数,具体取决于某些副作用。我将东西包装在IO monad中,但是根据最小功耗原则,实际上是在声明我的函数为koushik@koushik-HP-Notebook:~$ p4a apk [WARNING]: $ANDROIDNDKVER is deprecated and no longer necessary, the value you set is ignored [INFO]: Will compile for the following archs: armeabi-v7a [INFO]: Found Android API target in $ANDROIDAPI: 28 [ERROR]: Build failed: Could not find `android` or `sdkmanager` binaries in Android SDK [INFO]: Instructions: Make sure the path to the Android SDK is correct 。现在代码无法编译,我也不明白为什么,请提出可能有问题的

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)

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

1 个答案:

答案 0 :(得分:7)

问题在于F[_]: Effect中的上下文绑定到一个隐式参数中,因此编译器看到的是这样的东西:

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

这意味着每次尝试在方法的主体中解析隐式Effect[F]时,都会失败,因为它认为显式F和此合成ev含糊不清

解决方案是删除上下文绑定或显式的隐式F: Effect[F]参数。我建议取消上下文绑定,因为Scala允许您将两者结合在一起是造成这种错误非常容易的部分原因(在我看来,这是语言设计师的严重错误判断,因为我've said many times before)。