2017-08-21 5 views
0

を一般的な暗黙のインポート:私が作成し、私は、指定された型の暗黙の値を作成することができ、一般的な暗黙のプロバイダを作るためのラインで何かしようとしているクラスのインスタンスから

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._からインポートします。インスタンスが1つしかない限り、これは正常に動作します。しかし、時にはいくつかのタイプのための暗黙のは、一つの場所

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]] 
} 

に必要そして、これは​​とnot enough arguments for method implicitlyエラーでコンパイルに失敗しています。

プロバイダからの暗黙的な値を直接使用すると、すべてが再び機能し始めます。そこに各プロバイダ内の実際にいくつかの暗黙があり、可能であれば目標が抽象的にそれらであるよう

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

は、しかし、私は、個々の値をインポートしないようにしようとしています。

これは何とか実現できますか、あまりにもコンパイラから欲しいですか? aProviderevidencebProviderevidence

答えて

1

問題は、両方のオブジェクトからインポートするとき、あなたが名前を衝突した2つのエンティティに持っていることです。コンパイラは、実装されているために、また暗黙のうちに暗黙のうちに暗黙のうちに暗黙のうちに暗黙のうちに暗黙のうちに明示的に行うことができないという理由で、それらを曖昧にすることはできません。

私が理解できないのは、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._ 
// ... 
+0

を。 私の場合の 'ImplicitProvider'の実際の目的は、特定のタイプのオブジェクトに対してCirce' Encoder'/'Decoder'インスタンスを提供することです。これらの型はあらかじめわかっていないので、オブジェクトに既成のインスタンスを持つことはできません。私は、個々の 'Encoder' /' Decoder'をインポートしたり参照したりする必要なしに、ユーザのための最小定型化を達成しようとしていました。 暗黙の変換のヒントのおかげで、リンクが見つかりませんでした。それはちょうど必要なことをした。 –

関連する問題