Не удается найти экземпляр функтора для Tuple2K - PullRequest
0 голосов
/ 17 мая 2018

У меня есть игрушка 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._ , где экземпляр неявно определен .

Я не вижу, что я делаю неправильно, это должно быть что-то глупое. Есть ли у вас какие-либо идеи? Весь код можно увидеть в этой сущности .

Ответы [ 2 ]

0 голосов
/ 17 мая 2018

Компилятор жалуется, что не может найти экземпляр cats.Functor[[A]cats.data.Tuple2K[example.CoLogging,example.CoPersist,A]], хотя я импортирую cats.data.Tuple2K._ , где экземпляр неявно определен .

Functor[Tuple2K[F, G, ?]] определяется через Tuple2KInstances8#catsDataFunctorForTuple2K, если были определены Functor[F] и Functor[G]. Дело в том, что 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 в начало, и все должно скомпилироваться.

0 голосов
/ 17 мая 2018

Чтобы использовать функторы cats в вашем коде, вам нужно попытаться добавить настройки в ваш файл build.sbt.

scalacOptions += "-Ypartial-unification"

Может быть, это поможет тебе. Это ограничение компилятора scala https://issues.scala -lang.org / browse / SI-2712

...