通过 foldMap 组合 FunctionK
Compose FunctionK by foldMap
我有两个自由单子代数 DomainOp
和 DbOp
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
我有两个自由单子代数 DomainOp
和 DbOp
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 anF ~> G
into aFree[F, ?] ~> G