Значение flatMap не является членом параметра типа F[Long] при использовании cats.effect
Это, возможно, задавали много раз прежде, но ни одно из предложений, которые я нашел, не помогло.
У меня есть простой код 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 ответ
Проблема в том, что контекст связан в F[_]: Effect
desugars в неявный параметр, поэтому компилятор видит что-то вроде этого:
def generateId[F[_]](rid: Long)(implicit ev: Effect[F], F: Effect[F], ...): F[Long] = ...
Это означает, что каждый раз, когда он пытается разрешить неявное Effect[F]
в теле метода произойдет сбой, потому что он думает, что явное F
и этот синтетический ev
неоднозначны.
Решение состоит в том, чтобы удалить либо контекстную границу, либо явную неявную F: Effect[F]
параметр. Я бы предложил убрать границы контекста, поскольку тот факт, что Scala позволяет вам комбинировать эти два элемента, является одной из причин, по которой так легко допустить ошибку такого типа (и, на мой взгляд, это было серьезное недопонимание со стороны разработчиков языка, поскольку я сказал много раз раньше).