2016-05-17 87 views
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

這可能會也可能沒有幫助:https://tpolecat.github.io/2015/07/30/infer.html –

回答

2

這個問題的一般解決方法是創建一個新的類

  • 你想指定類型參數和
  • 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] 

你最終的東西,它看起來像一個函數調用的時候實際上是兩個有:

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

這是同樣的伎倆搶諾里斯在他的評論中@mz頁面上解釋說。

+0

謝謝!除了在原文中沒有提到的一個複雜性之外,這幾乎可以奏效:'mkWrapper'簽名實際上看起來像'mkWrapper [A:Manifest,B]',所以我必須攜帶'Manifest'東西,現在,當我寫'mkWrapper [Double](stuff)'時,它希望'stuff'是'Manifest' :(我可以寫'mkWrapper [Double] .apply(stuff)',這仍然是一個進步,但是完美主義者我不高興:( 任何想法如何解決? – Dima

+0

@DIM似乎在這種情況下,你可以添加一個額外的隱式'man:Manifest [A]'到'apply'函數(並且移除' :來自'mkWrapper'的Manifest'上下文綁定),但並不總是可以移動隱式參數。 –

相關問題