【问题标题】:Cannot find Bind instances for Free Monads over Coyoneda when composing functions via Kleisli arrows in scalaz通过 scalaz 中的 Kleisli 箭头组合函数时,无法在 Coyoneda 上找到 Free Monads 的 Bind 实例
【发布时间】:2015-09-09 15:42:53
【问题描述】:

提前感谢您的帮助

我尝试通过 Kleisli 箭头编写 2 个函数。这些函数接受字符串并生成 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 特征的 monad 实例中,我通过 import Free 导入所有 Free 隐含实例。_

我在这里错过了什么?

提前谢谢你!

【问题讨论】:

  • 你能提供一个可行的例子吗? type FreeString[A] = FreeC[F,String] 无法编译。
  • 我猜你的意思是type FreeString[A] = FreeC[Sensor, A]?
  • @TravisBrown 感谢您的回复。不,我的原始类型声明仍然存在并且它可以编译 - 但我没有为代码提供足够的上下文。我更新了代码 sn-p 以包含更多上下文。如果不是为了尝试进行 kleisli 组合,代码编译得很好。请注意:这里的大局是基于 Free Monad 的 dsl - 为简洁起见,我不包括其他代数。如果这没有意义,我可以将完整的代码放在一个要点中 - 让我知道。再次感谢您!

标签: scala functional-programming scalaz free-monad kleisli


【解决方案1】:

感谢特拉维斯的帮助。错误的类型声明实际上是罪魁祸首之一。在 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 是正确的类型声明并为 FreeCoF 提供类型类 monad 实例 implicit val MonadFreeSensor = Free.freeMonad[FreeCoF]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-09
    • 2013-12-08
    相关资源
    最近更新 更多