2016-05-17 14 views
1

はここに私のユースケースである:今1つの型パラメータを推論しますが、他の型パラメータは推測しませんか?

def mkWrapper[A,B](doer: StuffDoer[B])(implicit ev: A => B) = 
    new StuffDoer[A] { 
     override def doStuff(a: A) = doer.doStuff(ev(a)) 
    } 

、私はどこかで定義された

StuffDoer[AwfullyLong[Complicated,And],_ <: Difficult[ToRead],Type]

のインスタンスがあるとし、かつStringからの暗黙的な変換に...よく、にそのタイプ。

私はmkWrapper[String,_](doer)をどのように呼び出すことができるかの提案を探していて、それを綴る必要はなく、doerのタイプから2番目のタイプのパラメータを推測させます。

アイデア?

+2

これは役立つ場合もあります。https://tpolecat.github.io/2015/07/30/infer.html –

答えて

2

この問題の一般的な解決策は

  • 指定したいんtypeパラメータと
  • 型パラメータの残りの部分とapply方法で新しいクラスを作成することです。 catsCoproduct.left[X])とshapeless

いくつかの例(*Aux構文ヘルパークラス)。あなたのケースでは

これは次のようになります。

class WrapperHelper[A] { 
    def apply[B](doer: StuffDoer[B])(implicit ev: A => B) = 
    new StuffDoer[A] { 
     override def doStuff(a: A) = doer.doStuff(ev(a)) 
    } 
} 

def mkWrapper[A] = new WrapperHelper[A] 

次の2つが実際に存在する場合には、一つの関数呼び出しのようなもので終わる:

val stuff: StuffDoer[Int] = ??? 
mkWrapper[Double](stuff) 
mkWrapper[Double].apply(stuff) 

これは、同じトリックロブですNorrisは彼のコメントにリンクされている@mzページについて説明します。

+0

ありがとうございます! 'mkWrapper'は実際に' mkWrapper [A:Manifest、B] 'のように見えますので、' Manifest'を実行しなければなりません。 'mkWrapper [Double](stuff)'と書くと 'stuff 'が' Manifest'になります:('mkWrapper [Double] .apply(stuff)'を書くことができます。私は幸せではありません:( これを回避する方法はありますか? – Dima

+0

@Dimaこの場合、 'apply:'関数に余分な暗黙の 'man:Manifest [A]'を追加することができます( ' : 'mkWrapper'からバインドされたマニフェストのコンテキスト)ですが、暗黙のパラメータを移動することは必ずしも可能ではありません。 –

関連する問題