通过 foldMap 组合 FunctionK

Compose FunctionK by foldMap

我有两个自由单子代数 DomainOpDbOp

type DbFree[A] = Free[DbOp, A]

我写过两个解释器。一份用于 DomainOp ~> DbFree,一份用于 DbOp ~> Task。我想把解释器结合起来,这样我就可以有一个解释器DomainOp ~> Task。 Cats 中是否存在用于组合两个解释器的现有操作,其中该操作是第二个解释器上的 foldMap?我可以写类似下面的东西,但我很感兴趣是否已经存在这样的东西,因为它感觉像是免费 monad API.

的常见用例
  implicit class FreeFunctionKOps[F[_], G[_]](fk: FunctionK[F, ({ type L[H] = Free[G, H] })#L]) {
    def foldMapCompose[I[_]](fk2: FunctionK[G, I])(implicit I: Monad[I]): FunctionK[F, I] =
      new FunctionK[F, I] {
        override def apply[A](fa: F[A]): I[A] = fk(fa).foldMap(fk2)
      }
  }

我想你可以写一个 DbFree ~> DbOp 并与你现有的两个 FunctionKs:

组合
val f1: DomainOp ~> DbFree ...
val f2: DbOp ~> Task = ...
vla f3: DbFree ~> DbOp = new (DbFree ~> DbOp) {
  def apply[X](x: DbFree[X]): DbOp[X] = x.foldMap(FunctionK.id)
} // Or FunctionK.lift(_.foldMap(FunctionK.id))

f1 andThen f3 andThen f3

Peter Neyens: You could use cats.free.Free.foldMap which turns an F ~> G into a Free[F, ?] ~> G