我有两个免费monad代数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)
}
}
答案 0 :(得分:0)
我认为您可以写一个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
答案 1 :(得分:0)
Peter Neyens:您可以使用
cats.free.Free.foldMap
将F ~> G
变为Free[F, ?] ~> G