Cats中的效果抽象和并行执行

时间:2018-05-08 11:48:00

标签: scala functional-programming scala-cats

我有下一个使用Cats IO编写的代码,它并行执行多个动作(简化):

import cats.effect._
import cats.implicits._

import scala.concurrent.ExecutionContext.Implicits.global

    class ParallelExecIO {

        def exec: IO[List[String]] = {
            val foo = IO.shift *> IO("foo")
            val bar = IO.shift *> IO("bar")
            List(foo, bar).parSequence
        }
    }

是否可以使用效果抽象重写此代码?应提供哪些类型的证据?

样品:

class ParallelExecIO[F[_]: ConcurrentEffect /* ??? */] {

    def exec: F[List[String]] = {
        val foo = Async.shift[F](implicitly) *> "foo".pure[F]
        val bar = Async.shift[F](implicitly) *> "bar".pure[F]
        List(foo, bar).parSequence 
    }
}
  

[error] value parSequence不是List [F [String]]

的成员

1 个答案:

答案 0 :(得分:3)

使用

scalaVersion := "2.12.5"
scalacOptions += "-Ypartial-unification"
libraryDependencies += "org.typelevel" %% "cats-core" % "1.1.0"
libraryDependencies += "org.typelevel" %% "cats-effect" % "0.10"

错误是

Error:(23, 22) could not find implicit value for parameter P: cats.Parallel[F,F]
      List(foo, bar).parSequence

所以试试

import cats.Parallel
import cats.effect.{Async, ConcurrentEffect}
import cats.implicits._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.language.higherKinds

class ParallelExecIO[F[_]: ConcurrentEffect, G[_]](implicit ev: Parallel[F, G]) {

  def exec: F[List[String]] = {
    val foo = Async.shift[F](implicitly) *> "foo".pure[F]
    val bar = Async.shift[F](implicitly) *> "bar".pure[F]
    List(foo, bar).parSequence
  }
}

当然你可以介绍type Parallel[F[_]] = cats.Parallel[F, F],然后可以将其重写为class ParallelExecIO[F[_]: ConcurrentEffect : Parallel] {...