简体   繁体   English

通过 scalaz 中的 Kleisli 箭头组合函数时,无法在 Coyoneda 上找到 Free Monads 的 Bind 实例

[英]Cannot find Bind instances for Free Monads over Coyoneda when composing functions via Kleisli arrows in scalaz

Thank you in advance for your help预先感谢您的帮助

I have 2 functions that I am trying to compose via Kleisli arrows.我尝试通过 Kleisli 箭头编写 2 个函数。 The functions accept String and produce FreeC.这些函数接受 String 并生成 FreeC。 The kleisli arrows are created without an issue but the compiler is complaining that it cannot find.创建 kleisli 箭头没有问题,但编译器抱怨它找不到。 I will cut out some of the code for simplicity:为简单起见,我将删减一些代码:

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

}

For some reason what i get is this compilation error:出于某种原因,我得到的是这个编译错误:

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

feels like the implicit should be resolved since FreeC in a monad instance that implements a Bind trait and i am importing all of the Free implicit instances via import Free._感觉应该解决隐式问题,因为 FreeC 在实现 Bind 特性的 monad 实例中,我正在通过 import Free._ 导入所有 Free 隐式实例

what am I missing here?我在这里错过了什么?

Thank you in advance!先感谢您!

Thank you Travis for your help.谢谢特拉维斯的帮助。 Bad type declaration was actually one of the culprits.错误的类型声明实际上是罪魁祸首之一。 With some help from the scalaz community via google groups and some tinkering here is the answer:在 scalaz 社区通过 google 群组提供的一些帮助下,这里的一些修补是答案:

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

}

key is the correct type declaration and providing the type class monad instance for FreeCoF implicit val MonadFreeSensor = Free.freeMonad[FreeCoF]关键是正确的类型声明并为 FreeCoF 提供类型类 monad 实例隐式 val MonadFreeSensor = Free.freeMonad[FreeCoF]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM