不指定具体类型的Scala无标记词尾



我有一个服务,它看起来像这样:

无标签的最后特征:

trait ProvisioningAPIService[M[_]] {
def provisionAPI(request: Request): M[Response]
}

在我的实现中,我有以下内容:

class ProvisioningService extends ProvisioningAPIService[Task] {
def provisionAPI(request: Request): Task[Response] = Task {
Response("response from server")
}
}

这很好,但我仍然希望延迟,并仅在实例化ProvisioningService的新版本时传递效果。例如我想要这样的东西:

class ProvisioningService[M[_]: Monad](implicit monad: Monad[M[_]) extends ProvisioningAPIService[M] {
def provisionAPI(request: Request): M[Response] = /* some wrapper that would be resolved at runtime */ {
Response("response from server")
}
}

在运行时,我会执行以下操作:

val privisioingServiceAsTask = new ProvisioningService[Task]

因此,基本上我不会在编译时提供具体的实现,但我会创建一个在运行时传递效果的ProvisioningService实例。我该怎么做?

将注释移动到答案,

class MyClass[A : Monad]和说class MyClass[A](implicit m: Monad[A])是完全一样的,所以你不需要两者。在这种情况下,你实际上希望能够直呼其名,所以你应该更喜欢后者。

您可以在这里阅读Scala 3和Scala 2的上下文边界

现在让我们看看什么类型的类。类型类本质上以一种很好的方式实现了基于每个类型的重载。

因此,当您说在作用域中定义了Monad[A]时,这意味着A将定义Monad特性包含的3个操作。实现的细节被抽象掉了,所以我们不必担心它们。如果您查看Monad的页面,并扩展为Applicative,您会发现Monad的任何实例都要求您具有Pure的实现,该实现将值封装在类型构造函数中。对于给定的效果,这个pure所做的将留给实例的实现。例如,它可以是Future.successful

所以你可以有一些类似的东西

import cats._
import cats.effect.IO
case class Request(s: String)
case class Response(s: String)
trait ProvisioningAPIService[M[_]] {
def provisionAPI(request: Request): M[Response]
}
class ProvisioningService[M[_]](implicit monad: Monad[M]) extends ProvisioningAPIService[M] {
def provisionAPI(request: Request): M[Response] = monad.pure(Response("response from server"))
}
val privisioingServiceAsTask = new ProvisioningService[IO]

希望这能回答你的问题

相关内容

  • 没有找到相关文章

最新更新