通过foldMap撰写FunctionK

时间:2017-06-15 23:37:15

标签: scala scala-cats

我有两个免费monad代数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)
      }
  }

2 个答案:

答案 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.foldMapF ~> G变为Free[F, ?] ~> G