在需要 Concurrent 和 Timer 类型 class 实例的测试中使用什么类型?
What type to use in tests which require Concurrent and Timer type class instance?
考虑以下示例:
import cats.Functor
import cats.effect.{Concurrent, Timer}
import cats.syntax.functor._
import fs2.Stream
import scala.concurrent.duration._
class FetchAndSum[F[_]: Timer: Concurrent: Functor](fetch: List[String] => F[List[Int]]) {
def run(inputs: List[String]): F[Int] =
Stream
.emits(inputs)
.covary[F]
.groupWithin(20, 10.millis)
.mapAsync(10)(chunk => fetch(chunk.toList))
.flatMap(Stream.emits)
.reduce(_ + _)
.compile
.last
.map(_.getOrElse(0))
}
在生产中,这是用 IO
Monad 实例化的。
在我的测试中,我想测试 fetch
函数被调用了多少次。如果 F[_]
只需要一个 Functor
实例,我可以简单地使用 Writer
monad 来做到这一点。
由于fs2的mapAsync
和groupedWithin
,F[_]
必然也有Timer
和Concurrent
的实例,那些当然不存在在 Writer
.
我可以使用什么数据类型以功能方式对此进行测试?
我想过以某种方式将 IO
与 Writer
结合起来,例如type IOWriter[A] = IO[Writer[Int, A]]
,但如果不为 IOWriter
.
重新声明所有类型 class 实例,我就无法完成这项工作
有什么东西可以让我实现这一目标而不必重新声明所有类型 class 实例吗?
将 IO
与 Ref
一起使用:
val numsExecuted: IO[Int] = for {
ref <- Ref[IO].of(0)
fetch = (l: List[String]) => ref.update(_ + 1).as(???)
_ <- new FetchAndSum[IO](fetch).run(???)
x <- ref.get
} yield x
您还可以将 Writer
与 IO
结合使用。这个结构被称为 Writer monad transformer (type IOWriter[A] = cats.data.WriterT[IO, A]
),应该有 Concurrent / Timer / Monad / etc. 开箱即用的实例。
考虑以下示例:
import cats.Functor
import cats.effect.{Concurrent, Timer}
import cats.syntax.functor._
import fs2.Stream
import scala.concurrent.duration._
class FetchAndSum[F[_]: Timer: Concurrent: Functor](fetch: List[String] => F[List[Int]]) {
def run(inputs: List[String]): F[Int] =
Stream
.emits(inputs)
.covary[F]
.groupWithin(20, 10.millis)
.mapAsync(10)(chunk => fetch(chunk.toList))
.flatMap(Stream.emits)
.reduce(_ + _)
.compile
.last
.map(_.getOrElse(0))
}
在生产中,这是用 IO
Monad 实例化的。
在我的测试中,我想测试 fetch
函数被调用了多少次。如果 F[_]
只需要一个 Functor
实例,我可以简单地使用 Writer
monad 来做到这一点。
由于fs2的mapAsync
和groupedWithin
,F[_]
必然也有Timer
和Concurrent
的实例,那些当然不存在在 Writer
.
我可以使用什么数据类型以功能方式对此进行测试?
我想过以某种方式将 IO
与 Writer
结合起来,例如type IOWriter[A] = IO[Writer[Int, A]]
,但如果不为 IOWriter
.
有什么东西可以让我实现这一目标而不必重新声明所有类型 class 实例吗?
将 IO
与 Ref
一起使用:
val numsExecuted: IO[Int] = for {
ref <- Ref[IO].of(0)
fetch = (l: List[String]) => ref.update(_ + 1).as(???)
_ <- new FetchAndSum[IO](fetch).run(???)
x <- ref.get
} yield x
您还可以将 Writer
与 IO
结合使用。这个结构被称为 Writer monad transformer (type IOWriter[A] = cats.data.WriterT[IO, A]
),应该有 Concurrent / Timer / Monad / etc. 开箱即用的实例。