Bounds for type parameter of FunctionK

前端 未结 2 1247
日久生厌
日久生厌 2021-01-14 00:22

I\'m using cats FreeMonad. Here\'s a simplified version of the algebra:

sealed trait Op[A]

object Op {
    final case class Get[T](name: String         


        
2条回答
  •  死守一世寂寞
    2021-01-14 00:56

    I think I've found a way to solve your problem by combining a ReaderT monad transformer with intersection types:

    import scala.concurrent.Future
    import cats.~>
    import cats.data.ReaderT
    import cats.free.Free
    
    object FreeMonads {
      sealed trait Op[A]
    
      object Op {
        final case class Get[T](name: String) extends Op[T]
        type OpF[A] = Free[Op, A]
        def get[T](name: String): OpF[T] = Free.liftF[Op, T](Get[T](name))
      }
    
      trait Resource
      trait Format[A]
      trait Definition[A]
    
      trait Client {
        def get[O <: Resource](name: String)
          (implicit f: Format[O], d: Definition[O]): Future[O]
      }
    
      type Result[A] = ReaderT[
        Future,
        (Format[A with Resource], Definition[A with Resource]),
        A,
      ]
    
      class FutureOp(client: Client) extends (Op ~> Result) {
        def apply[A](fa: Op[A]): Result[A] =
          fa match {
            case Op.Get(name: String) =>
              ReaderT {
                case (format, definition) =>
                  // The `Future[A]` type ascription makes Intellij IDEA's type
                  // checker accept the code.
                  client.get(name)(format, definition): Future[A]
              }
          }
      }
    }
    

    The basic idea behind it is that you produce a Reader from your Op and that Reader receives the values that you can use for the implicit params. This solves the problem of type O having instances for Format and Definition.

    The other problem is for O be a subtype of Resource. To solve this, we're just saying that the Format and Definition instances are not just instances of any A, but any A that also happens to be a Resource.

    Let me know if you bump into problems when using FutureOp.

提交回复
热议问题