2011-07-08 10 views
4

Scalaで型パラメータ化されたメソッドを呼び出すときにデフォルトの型を持つことができるかどうかを知りたいと思います。コンパイラは推測するためにどのようなタイプについてのヒントを持っていないときに私は、AStringになりたいメソッド呼び出しのデフォルトのタイプ

def apply[A](id: String)(implicit processor: Processor[A]) = 
    processor(data get id) 

:私はどこかに次のような方法があるとします。だから、私は私の定義をオーバーロードすることができます

def apply(id: String)(implicit processor: Processor[String]) = 
    processor(data get id) 

しかし、両方の方法は、消去後に同じシグネチャを持つことになります...デフォルトのタイプを提供する方法はありますか?あなたは少しトリックより一般的な文脈では

class C { 
    def apply[A](id: String) = (processor: Processor[A]) => id + processor 
    def apply(id: String)(implicit processor: Processor[String]) = id + processor 
} 

、全く分からないのSRYを使用することができます。この場合

答えて

7

次のファントムt YPE:

sealed class DefaultsTo[A, B] 
trait LowPriorityDefaultsTo { 
    implicit def overrideDefault[A,B] = new DefaultsTo[A,B] 
} 
object DefaultsTo extends LowPriorityDefaultsTo { 
    implicit def default[B] = new DefaultsTo[B, B] 
} 

次に、あなたの方法は、任意の指定された2つの種類、ABのために、コンパイラは常にタイプDefaultsTo[A, B]のオブジェクトを供給できることを

def apply[A](id: String)(implicit e: A DefaultsTo String, 
            processor: Processor[A]) = 
    processor(data get id) 

overrideDefault保証の定義を記述することができ(例えば、 DefaultsTo[Int, String])。しかし、2つのタイプのうちの1つ(例えば、DefaultsTo[A, String])が指定されていない場合、コンパイラは2つのタイプ(DefaultsTo[String, String]を供給しているため、Aの場合はString)を識別します。 Naftoli Gugenheim pointed out in this mailing list threadとして

、あなたはまた、コンテキスト境界で使用するためのいくつかの素晴らしい構文を達成することができます:

class Has[B] { 
    type AsDefault[A] = A DefaultsTo B 
} 

def apply[A : Has[String]#AsDefault : Processor](id: String) = 
    implicitly[Processor[A]].apply(data get id) 
+1

[この質問を参照](http://stackoverflow.com/questions/4403906/is-it-possible-in-scala-to-force-the-caller-to-specify-a-type-parameter-for-a -pol)。 –

0

...

EDIT

私はあなたがprocessorする必要が忘れてしまいましたimplicitなので、コンパイルされません。

+0

彼は暗黙のうちにプロセッサを供給するようにコンパイラを望んでいる場合は動作しません。 –

+0

イェップ、ちょうど自分自身、気づいたとにかく。 – agilesteel

関連する問題