[英]Scala Tagless Final Without Specifying a Concrete Type
我有一個看起來像這樣的服務:
無標簽的最終特征:
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 的上下文邊界
現在讓我們看看什么是Type Classes。 類型類本質上以一種很好的方式啟用了每個類型的重載。
因此,當您說您在 scope 中定義了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]
希望這能回答你的問題
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.