我有类似的东西
def test[F[_]: Sync: Console](counter: Int): F[Unit] =
for {
_ <- if(counter % 10000 == 0) Console[F].println(s"counter: ${counter}") else Sync[F].unit
_ <- test( counter + 1 )
} yield ()
并想添加
_ <- Temporal[F].sleep(50.milliseconds)
在 for 语句中。但是添加(当时必要的)上下文绑定
: Temporal
会导致编译错误Cannot resolve symbol flatMap
。这段代码有什么问题?
我试过附加参数
(implicit T: Temporal[F])
而不是
: Temporal
,但得到同样的错误。
Sync
和Temporal
都是Monad
/FlatMap
,这种隐含的歧义混淆了如何将理解脱糖成.flatMap
/.map
的链。
因为
Sync
现在只用于 .unit
并且 Temporal
已经有 monadic .unit
,一个选择是删除上下文绑定 : Sync
import cats.effect.Temporal
import cats.effect.std.Console
import cats.syntax.flatMap._
import cats.syntax.functor._
import scala.concurrent.duration._
def test[F[_]: Console : Temporal](counter: Int): F[Unit] =
for {
_ <- if (counter % 10000 == 0) Console[F].println(s"counter: ${counter}")
else Temporal[F].unit
_ <- test(counter + 1)
_ <- Temporal[F].sleep(50.milliseconds)
} yield ()
另一种选择是手动对 for-comprehension 进行脱糖,并明确指定
Monad
中的哪个 Sync[F]
实例,Temporal[F]
用于 .flatMap
import cats.effect.{Sync, Temporal}
import cats.effect.std.Console
import scala.concurrent.duration._
def test[F[_]: Sync : Console : Temporal](counter: Int): F[Unit] = {
val x: F[Unit] =
if (counter % 10000 == 0) Console[F].println(s"counter: ${counter}")
else Sync[F]/*Temporal[F]*/.unit
val y: F[Unit] = Sync[F]/*Temporal[F]*/.flatMap(x)(_ => test(counter + 1))
Sync[F]/*Temporal[F]*/.flatMap(y)(_ => Temporal[F].sleep(50.milliseconds))
}