简体   繁体   中英

value flatMap is not a member of type parameter F[Long] when using cats.effect

This perhaps been asked many times before, but none of the suggestions I've found help.

I have a simple Scala code that generates long number that depends on some side-effects. I'm wrapping thing in an IO monad, but according to the least power principle, I'm actually declaring my function as F[_]: Effect . Now code won't compile and I don't understand why, please suggest what may be wrong

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)

Also, if you have any suggestions on improving the code, let me know please.

The problem is that the context bound in F[_]: Effect desugars into an implicit parameter, so the compiler is seeing something like this:

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

That means that every time it tries to resolve an implicit Effect[F] in the body of the method, it'll fail because it thinks the explicit F and this synthetic ev are ambiguous.

The solution is to drop either the context bound or the explicit implicit F: Effect[F] parameter. I'd suggest killing the context bound, since the fact that Scala allows you to combine the two is part of the reason it's so easy to make this kind of error (and was in my view a serious misjudgement by the language designers, as I've said many times before ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM