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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用cats.effect时,value flatMap不是类型参数F [Long]的成员相关的知识,希望对你有一定的参考价值。

这或许曾多次被问过,但我找到的建议都没有帮助。

我有一个简单的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中的上下文绑定到一个隐式参数,所以编译器看到的是这样的:

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

这意味着每次它试图解析方法体中的隐式Effect[F]时,它都会失败,因为它认为显式的F和这个合成的ev是不明确的。

解决方案是删除上下文绑定或显式隐式F: Effect[F]参数。我建议删除上下文绑定,因为Scala允许你将两者结合起来这一事实是因为它很容易造成这种错误(并且在我看来是语言设计者的一个严重错误判断,因为我'said many times before)。

以上是关于使用cats.effect时,value flatMap不是类型参数F [Long]的成员的主要内容,如果未能解决你的问题,请参考以下文章

tf.ragged.map_flat_values

带有 flat=true 的 Values_list 仍然显示 <QuerySet [..]>

带有 flat=True 的 Values_list 仍然显示括号

boost flat_map 批量插入

django获取某一个字段的列表,values/values_list/flat

关于ES6的flat(扁平化数组)