1

我有一个玩具 DSL

case class Logging[A](msg: String, action: A)
case class Persist[A](msg: String, action: A)
type Effect[A] = EitherK[Logging, Persist, A]

我想与一个同样玩具的口译员配对

case class CoLogging[A](run: String => A)
case class CoPersist[A](run: String => A)
type Interp[A] = Tuple2K[CoLogging, CoPersist, A]

这是一个程序示例:

def prog(implicit L: Logs[Effect], P: Persists[Effect]): Free[Effect, Unit] =
  P.store("bar") >> L.log("foo")

这是口译员:

def interpretEffect(implicit CL: CoLogs[IO], CP: CoPersists[IO]): Cofree[Interp, IO[Unit]] = 
  Cofree.unfold(IO.pure(())) { a: IO[Unit] => Tuple2K(CoLogging(CL.coLog(a)), CoPersist(CP.coPersist(a))) }

我已经进行了尽职调查并定义了函子以及注入隐式。编译器抱怨它找不到实例cats.Functor[[A]cats.data.Tuple2K[example.CoLogging,example.CoPersist,A]],即使我正在导入cats.data.Tuple2K._ 隐式定义的实例

我看不出我做错了什么,这一定是愚蠢的。你有什么主意吗?所有代码都可以在这个 gist中看到。

4

2 回答 2

1

编译器抱怨它找不到实例 cats.Functor[[A]cats.data.Tuple2K[example.CoLogging,example.CoPersist,A]],即使我正在导入cats.data.Tuple2K._ 隐式定义的实例

Functor[Tuple2K[F, G, ?]]是通过Tuple2KInstances8#catsDataFunctorForTuple2KifFunctor[F]Functor[G]were defined 定义的。事情是这样的Functor[CoLogging]Functor[CoPersist]但不是。

添加

object CoLogging {
  implicit val coLoggingFunctor: Functor[CoLogging] = new Functor[CoLogging] {
    override def map[A, B](fa: CoLogging[A])(f: A => B): CoLogging[B] = CoLogging(fa.run andThen f)
  }
}

object CoPersist {
  implicit val coPersistFunctor: Functor[CoPersist] = new Functor[CoPersist] {
    override def map[A, B](fa: CoPersist[A])(f: A => B): CoPersist[B] = CoPersist(fa.run andThen f)
  }
}

一切都应该编译。

事情是隐含的顺序。将对象functors移到开头,一切都应该编译。

于 2018-05-17T11:05:57.817 回答
0

要在代码中使用猫函子,您需要尝试在 build.sbt 文件中添加设置。

scalacOptions += "-Ypartial-unification"

也许这会帮助你。这是 scala 编译器的限制https://issues.scala-lang.org/browse/SI-2712

于 2018-05-17T07:18:30.103 回答