Значение flatMap не является членом параметра типа F [Long] при использовании cats.effect - PullRequest
0 голосов
/ 18 февраля 2019

Это, возможно, задавали много раз раньше, но ни одно из предложений, которые я нашел, не помогло.

У меня есть простой код Scala, который генерирует длинное число, которое зависит от некоторых побочных эффектов.Я помещаю вещи в монаду ввода / вывода, но по принципу наименьшей мощности я фактически объявляю свою функцию как 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)

Также, если у вас есть какие-либо предложения по улучшению кода, дайте мне знать, пожалуйста.

1 Ответ

0 голосов
/ 18 февраля 2019

Проблема в том, что контекст, связанный в F[_]: Effect, десугарсирует в неявный параметр, поэтому компилятор видит что-то вроде этого:

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

Это означает, что каждый раз, когда он пытается разрешить неявный Effect[F] в теле метода произойдет сбой, потому что он считает явное F и это синтетическое ev неоднозначными.

Решение состоит в том, чтобы удалить либо контекстную границу, либо явную неявную F: Effect[F] параметр.Я бы предложил убрать границы контекста, поскольку тот факт, что Scala позволяет вам комбинировать эти два элемента, является одной из причин, по которой так легко допустить ошибку такого типа (и, на мой взгляд, это было серьезное недопонимание со стороны разработчиков языка, поскольку я' сказал много раз до ).

...