2012-07-27 3 views
5

型パラメータによって異なる動作をする関数を記述したいと思います。私が何をしたいの 簡単な例を以下に示します。私はC++テンプレートのスペシャライゼーションと同様にScalaで関数型パラメータを特化できますか?

def f[Int] = "I'm an int" 
def f[Float] = "I'm a float" 
def f[Burger] = "You want fries with that?" 

はScalaでの可能なこのですか私の周りの作品のいくつかの種類が必要なのですか?

答えて

14

直接ではありません。 Scalaでこれを行う通常の方法はtypeclassです。

trait FAble[T] { def doF: String } 
object FAble { 
    implicit val fInt = new FAble[Int] { def doF = "I'm an int" } 
    implicit val fFloat = new FAble[Float] { def doF = "I'm a float" } 
    implicit val fBurger = new FAble[Burger] { def doF = "You want fries?" } 
} 

def f[T](implicit ev: FAble[T]) = ev.doF 
// or 
def f[T: FAble] = implicitly[FAble[T]].doF 

それは公平なビットより冗長だが、それはあまりにもいくつかの利点を持っている - 暗黙のインスタンスは(implicit defの代わりにval Sを使用して)計算することができ、かつ任意のタイプのために複数のインスタンスがありますこれを使用すると、コードの異なるポイントで異なるインスタンスをスコープ内に持つことで、ビヘイビアを選択できます。

C++の方法ではできない理由は、Scalaのジェネリックスでは、異なるタイプパラメータ(@specializedを除いて、どちらも必要ないので)のコード生成が含まれていないということです。だから、 "一般的なテンプレートのコードを生成する代わりに、この位置でIntを見ると、コンパイラは、この特定のコードを代わりに使用する"と言っても意味がありません。

1

マクロを調べることができます:http://scalamacros.org/。マクロは、コンパイル時に実行されるカスタム関数であり、コンパイル時の計算に基づいてコードを動的に生成できます。あなたが証拠を使用することを

2

別の可能なアプローチは次のとおりです。私ははるかにエレガントな解決策として、型クラスをお勧めしますしかし

def f[T](t:T)(implicit ev: T<:<Float) { 

// float version 

} 

def f[T](t:T)(implicit ev: T<:<Int) { 

// int version 

} 

関連する問題