2016-08-31 18 views
2

静的に利用できる(特性によって縮小されている)関数を持つクラスが必要です。次に、タイプパラメータとしてそのような型を取り、縮小された静的関数にアクセスする型パラメータ化メソッドが必要です。 (静的という用語はScalaではなく、私が何を意味するのかを知っています)コンパイラ型のスカラ型制約

私がScalaで静的関数を持つことを知っている唯一の方法は、コンパニオンオブジェクトに特性を拡張させることです。しかしそれには2つの問題があります:

  1. コンパイルオブジェクトがいくつかの特性を拡張するようにタイプパラメータを制約する方法はわかりません。
  2. クラスが実際にコンパニオンオブジェクトと異なるタイプの静的メソッドにどのようにアクセスするのか分かりません。

これは完全にオフにすることが、ちょっと私は何をしたいです可能性があります

MyTrait { 
    def MyFunction() : Any //some function 
} 

case class MyClass(i: Int) 

object MyClass extends MyTrait { 
    def MyFunction() = {/*do stuff*/} 
} 

//need the type as a class not an object because I need it for a higher order function like this 
def SomeFunctionHigherOrderFunction[T /*constrain T such that the companion object of T <: MyTrait*/](someFunc : Function1[T, Any]) : Unit { 
    val someStuff = T.MyFunction() 
    /*use someStuff in here*/ 
} 

SomeFunctionHigherOrderFunction[T](/*provide a Function1[T, Any]*/); 

正解か、この問題について行くのいくつかのより良い方法の任意のアイデア?

ありがとうございます!

+1

を経由してそれを使用するあなたが持っている:この

implicit object MyClass extends MyTrait[MyClass] { def MyFunction = ... } 

それとも、そのオブジェクトで何かを持っていない場合、あなたもちょうどインラインそれを行うことができますような何かあなたのコードのいくつかのタイプミス。 [あなたが私たちに与えた例をコンパイルできることを確認してください!](http://sscce.org/) –

答えて

0

これを行う方法はありません。あなたが取ることができる1つのアプローチは、メソッドをvia implicitsに渡すことです(これはtypeclassアプローチとも呼ばれます)。 T以上の特性をパラメータ化する必要があります(使用しない場合でも、暗黙的に解決するためにTが使用されます)。

trait MyTrait[T] { 
    def MyFunction() : Any //some function (usually you want to use `T` somehow) 
} 

次に、コンパニオンオブジェクトを暗黙的に宣言します。

implicit val myTraitMyClass: MyTrait[MyClass] = new MyTrait[MyClass] { 
    def MyFunction = ... 
} 

そして

def SomeHigherOrderFunction[T](someFunc : Function1[T, Any])(implicit o: MyTrait[T]): Unit { 
    val someStuff = o.MyFunction() 
    /*use someStuff in here*/ 
} 
+0

このソリューションは素晴らしいです!唯一のことは、 '暗黙オブジェクトMyClass'はトップレベルエンティティとして定義できないということです。これは、別のクラスの中にオブジェクトを入れ子にして、余分なインポートを必要とするためです。少し厄介な)。共有のために@Alecに感謝します。 – Danny