2017-05-10 15 views
2

パラメータタイプ抽象型を参照しない場合があり

trait A { 
    type C 

    val Extract: { 
    def unapply(c: C): Option[Int] 
    } 
} 

エラーは以下の通りです:

error: Parameter type in structural refinement may not refer to an abstract type defined outside that refinement

私は上記を書きたいです私はパターンAで使用することができるように、特性Aのユーザーにオブジェクトまたはunapplyメソッドを持つ値を定義させます。
"Parameter type in structural refinement may not refer to an abstract type defined outside that refinement"Scala: "Parameter type in structural refinement may not refer to an abstract type defined outside that refinement"(以下を参照)のおかげで2つの回避策が見つかりましたが、最初のものは特性の継承を強制します。これは外部ライブラリにリンクしようとすると実行できません。 2番目の方法では、より多くのメソッドを追加するためにExtractをオーバーライドする可能性が失われます。

回避策

trait A { 
    type C 

    trait Extractable { 
    def unapply(c: C): Option[Int] 
    } 

    val Extract: Extractable 
} 

trait A { 
    type C 

    def extract(c: C): Option[Int] 

    object Extract { 
    def unapply(c: C): Option[Int] = extract(c) 
    } 
} 

私は、ユーザーが彼が望んでいるExtract方法を実装することができないという考えを表現することができます(構造タイプ以外多分他の)どのような方法があり、それは方法のunapplyを持って提供要求された署名?

答えて

1

タイプクラスを検討しましたか? Aは、型パラメータが "抽出可能"でなければならない、つまり範囲内にExtractable[C]という暗黙の値がなければならないことを示しています(unapplyを実装することのみを要求します)。これは、あなたから、他の図書館から、またはユーザー自身から来ることができます。

これは、特定のタイプのExtractable[C]を同時に複数持つことができないことを意味します。C;つまり、特定のタイプのあるタイプのExtractableの実装が1つだけです(Intなど)。これはあなたのユースケースに合わせられていますか?

trait Extractable[C] { 
    def unapply(c: C): Option[Int] 
} 

// user can supply his own extractable: 
implicit val myExtractableInt = new Extractable[Int] { 
    def unapply(c: Int): Option[Int] = Some(c) 
} 

// class A is parameterized by some C 
// for which Extractable[C] must exist 
class A[C : Extractable] { 
    val c: C = ??? 
    implicitly[Extractable[C]].unapply(c) 
} 

EDIT:

A形質を作るために、我々は(まだ別)の回避策が必要です。私はそれが特色である必要は除きはいそれはほとんど、仕事と

trait Extractable[C] { 
    def unapply(c: C): Option[Int] 
} 

// class A is parameterized by C 
// for which Extractable[C] must exist 
trait A[C] { 
    implicit def e: Extractable[C] 
    val c: C = ??? 
    e.unapply(c) 
} 

class SomeClass extends A[Int] { 
    // we need an implicit Extractable[Int], 
    // either from some import or custom one 
    implicit def e = new Extractable[Int] { 
    def unapply(c: Int): Option[Int] = Some(c) 
    } 
} 
+0

を理由があります私は別のものにミックスする必要があるいくつかの 'A'のようなものです。また、形質には暗黙的なパラメーターやパラメーターがない場合もあります。 –

+1

編集したバージョンのヘルプはありますか?これはまだ回避策ですが、これにはかなり柔軟性があるはずです。 – slouc

+0

@MikaëlMayerこれは解決されましたか? – slouc

関連する問題