簡體   English   中英

從類實例導入通用隱式

[英]Importing generic implicits from class instances

我正在嘗試創建一個通用的隱式提供程序,該提供程序可以為給定類型創建隱式值,如下所示:

trait Evidence[T]

class ImplicitProvider[T] {
  class Implementation extends Evidence[T]
  implicit val evidence: Evidence[T] = new Implementation
}

要使用此隱式,我在必要時創建一個val provider = new ImplicitProvider[T]實例,並從中import provider._ 只要只有一個實例,此方法就可以正常工作。 但是有時在一個地方需要幾種類型的隱式

case class A()
case class B()

class Test extends App {
  val aProvider = new ImplicitProvider[A]
  val bProvider = new ImplicitProvider[B]

  import aProvider._
  import bProvider._

  val a = implicitly[Evidence[A]]
  val b = implicitly[Evidence[B]]
}

而且無法編譯, could not find implicit value for parameternot enough arguments for method implicitly錯誤not enough arguments for method implicitly

如果我直接使用提供程序的隱式val,那么一切都會再次開始工作。

implicit val aEvidence = aProvider.evidence
implicit val bEvidence = bProvider.evidence

但是,我試圖避免導入單個值,因為每個提供程序中實際上都有多個隱式對象,目標是在可能的情況下抽象它們。

可以通過某種方式實現,還是我希望編譯器提供太多?

問題是,當你從兩個對象導入,你就帶來兩個實體已經發生碰撞的名字: evidenceaProviderevidencebProvider 編譯器不能消除它們的歧義,這不僅是因為其實現方式,而且因為對於隱式對象(可能已經是奧秘的)而言,要能夠執行無法顯式完成的工作(在沖突的名稱之間進行歧義化),這不是一個好主意。

我不明白的是ImplicitProvider的意義是什么。 您可以拉動Implementation類向頂層,有一個object的地方,保持implicit val秒。

class Implementation[T] extends Evidence[T]

object Evidence {
  implicit val aEvidence: Evidence[A] = new Implementation[A]
  implicit val bEvidence: Evidence[B] = new Implementation[B]
}

// Usage:
import Evidence._
implicitly[Evidence[A]]
implicitly[Evidence[B]]

現在,沒有名稱沖突。

如果您需要一個實際的ImplicitProvider ,則可以執行以下操作:

class ImplicitProvider[T] { ... }

object ImplicitProviders {
  implicit val aProvider = new ImplicitProvider[A]
  implicit val bProvider = new ImplicitProvider[B]

  implicit def ImplicitProvider2Evidence[T: ImplicitProvider]: Evidence[T]
    = implicitly[ImplicitProvider[T]].evidence
}

// Usage
import ImplicitProviders._
// ...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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