簡體   English   中英

Scala 無標簽最終沒有指定具體類型

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM