我有一個看起來像這樣的服務:
無標簽的最終特征:
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 的一個實體,在運行時傳遞了一個效果。我怎樣才能做到這一點?
uj5u.com熱心網友回復:
將評論移至答案,
說和說class MyClass[A : Monad]
是完全一樣的,class MyClass[A](implicit m: Monad[A])
所以你不需要兩者。在這種情況下,您實際上希望能夠按名稱呼叫它,因此您應該更喜歡后者。
您可以在此處閱讀有關 Scala 3和 Scala 2的背景關系邊界的資訊
現在讓我們看看什么是Type Classes。型別類本質上以一種很好的方式啟用了每個型別的多載。
因此,當您說您Monad[A]
在范圍內定義了一個,這意味著將定義 trait 包含A
的 3 個操作。Monad
實作的細節被抽象出來,所以我們不必擔心它們。如果您查看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]
希望這能回答你的問題
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/508579.html