2017-02-01 10 views
0

悪いタイトルを申し訳ありません。
私は、この形質の基本形質と複数のインプリメンテーションを持つライブラリを使用しています。しかし、従来のメソッドオーバーライドの代わりに、暗黙的な引数を取るメソッドによってメソッドの特殊化が提供されています。実行時に最も正確に暗黙的に取得

class Cont[TT](val n : Int) 

trait I[ +Self ] { 
    final def foo[TT >: Self](implicit num : Cont[TT]) = num.n 
} 

trait B extends I[B] 

object B { 
    implicit def Mint : Cont[B] = new Cont[B](53) 
} 

class S extends B with I[S] 

object S{ 
    implicit def HMint : Cont[S] = new Cont[S](54) 
} 

Bが(うちSは一例である)は、いくつかのサブクラスを有するであろうその「基本タイプ」で次のように一般的なパターンです。このサブクラスのそれぞれは、(例ではContと同じように)いくつかの意味を提供します。これは、それぞれのメソッドを専門にしたいものです。特定の暗黙的なものが定義されていない場合は、Bのものが使用されます(上記のコードには示されていません)。実際にBとそのサブクラスで呼び出すメソッドは、特性Iで定義され、それぞれに1つのタイプがあります。
私の問題は、引数としてBまたはそのサブクラスのコレクションとそのメソッドを呼び出す汎用関数を記述したいが、最も具体的なimplicitsを呼びたいと思っている。 問題は、メソッドのオーバーライドとは異なり、「コンパイル時」タイプはどのメソッドが呼び出されるかを定義します。例:

val s = new S 
val b : B = s 
(b.foo,s.foo) 
res50: (Int, Int) = (53,54) 

最も一般的なメソッドを呼び出す方法で汎用関数を記述できますか?もしそうでなければ、それを可能にするライブラリーに軽い変更がありますか?最後に、このライブラリで使用されるパターンに名前が付いていますか?名前がわからないパターンについての情報を探すのは本当に難しいです。

答えて

1

あなたは渡されたパラメータとして基本型を取る一般的な関数を書くことができますが、そのタイプのメンバー・メソッドをしたい場合は、派生型を決定する必要があります。

def f(b:B) = b match { 
    case s:S => s.foo 
    case _ => b.foo 
} 
f(new S) // res0: Int = 54 

P.S.ああ、そのパターンに名前があるかどうかはわかりません。

関連する問題