Не удается найти экземпляры Bind для Free Monads над Coyoneda при составлении функций с помощью стрелок Клейсли в scalaz

Заранее спасибо за вашу помощь

У меня есть 2 функции, которые я пытаюсь составить с помощью стрелок Клейсли. Функции принимают String и выдают FreeC. Стрелки kleisli создаются без проблем, но компилятор жалуется, что не может найти. Я вырежу часть кода для простоты:

import scalaz._
import Scalaz._
import Free.FreeC
import Free._
import Kleisli._

trait AppCompose {

  def lift[F[_], G[_], A](fa: F[A])(implicit I: Inject[F, G]): FreeC[G, A] =
    Free.liftFC(I.inj(fa))

}

object BigBrother {

  sealed trait Sensor[A]
  case class Log(log: String) extends Sensor[Unit]
  case class Filter(log: String) extends Sensor[String]
  case class Secure(log: String) extends Sensor[String]

}

import BigBrother.Sensor

class BigBrother[F[_]](implicit I: Inject[Sensor,F]) extends AppCompose {
  import BigBrother._

  type FreeString[A] = FreeC[F,String]

  def log(log: String) = lift(Log(log))
  def filter(log: String) = lift(Filter(log))
  def secure(log: String) = lift(Secure(log))

  def filterAndSecure(phrase: String) = for {
    f <- filter(phrase)
    s <- secure(f)
  } yield s

  // kleisli composition attempt - alternative to filterAndSecure
  val fk = kleisli[FreeString, String, String](filter _)
  val sk = kleisli[FreeString, String, String](secure _)
  val fAndS = fk >=> sk // this is where we have a compilation issue

}

По какой-то причине я получаю ошибку компиляции:

could not find implicit value for parameter b: scalaz.Bind[FreeString]
[error]   val fAndS = sk >=> fk

кажется, что неявное должно быть разрешено, поскольку FreeC в экземпляре монады, который реализует черту Bind, и я импортирую все неявные экземпляры Free через импорт Free._

что мне здесь не хватает?

Заранее спасибо!

1 ответ

Решение

Спасибо Тревис за вашу помощь. Плохое объявление типа было на самом деле одним из виновников. С некоторой помощью сообщества скалаза через гугл-группы и некоторого возни здесь есть ответ:

class BigBrother[F[_]](implicit I: Inject[Sensor,F]) extends AppCompose {
  import BigBrother._

  def log(log: String) = lift(Log(log))
  def filter(log: String) = lift(Filter(log))
  def secure(log: String) = lift(Secure(log))

  def filterAndSecure(phrase: String) = for {
    f <- filter(phrase)
    s <- secure(f)
  } yield s

  type CoyoF[A] = Coyoneda[F, A]
  type FreeCoF[A] = Free[CoyoF,A]

  implicit val MonadFreeSensor = Free.freeMonad[FreeCoF]

  // kleisli composition attempt - alternative to filterAndSecure
  val fk = kleisli[FreeCoF, String, String](filter _)
  val sk = kleisli[FreeCoF, String, String](secure _)
  val fAndS = fk >=> sk

}

ключ является правильным объявлением типа и обеспечивает экземпляр монады класса типа для неявного FreeCoF val MonadFreeSensor = Free.freeMonad[FreeCoF]

Другие вопросы по тегам