2014-05-07 24 views
1

我試圖隱式地將一個類實例解構成一個元組來創建一個更好的DSL語法。Scala implicit unapply

這裏是什麼,我試圖做一個簡單的例子:

class Pair[A,B](a: A, b: B){ 
    def left = a 
    def right = b 
} 
val pair = new Pair(1,2) 
implicit def unpair[T1 <: Int, T2 <: Int](p: Pair[T1,T2]) = { 
    (p.left, p.right) 
} 
val(a,b) = pair 

結果:

error: constructor cannot be instantiated to expected type; 
found : (T1, T2) 
required: Pair[Int,Int] 

我知道我可以定義一個同伴對象與不應用方法和手工處理的解構(或者明確地隱含地稱呼),但是這造成不需要的樣板。

編輯 好,只需提供更多的上下文中,Pair被嵌入一個實現地圖,flatMap一個實例內,並且withFilter(即要被內,用於推導使用)。因此,期望使用看起來像:

val q = for{ 
    (a,b) <- tableA join tableB on(...) 
    (c,d) <- tableC leftJoin tableD on(...) 
    .... 
} yield(a,b,c,d,...) 

我想要什麼,以避免正在對情況類(或添加自定義的同伴對象存在的Pair類),並具有Pair(a,b) <- tableA join tableB on(...)每次我連接表(讀:常)

原始

有沒有辦法在斯卡拉2.10或2.11拉這一關?從2.8/2.9天開始,有一些較舊的SO線程表明這種功能是不可能的,但是希望自那時起事情發生了變化,或者有可用的解決方法。

回答

2

您需要設置類型a和b明確:

val(a,b): (Int, Int) = pair 
+0

有趣的是,雖然在DSL的背景下,將創建更多的樣板比手動不適用。例如val(u,o):(Users,Orders)= pair,vs val(u,o)= unpair(pair) – virtualeyes

+0

所以,我認爲你需要在這種情況下使用伴隨對象。導致val(a,b)...它是模式匹配,並且爲此設計了unapply。在DSL的情況下,我認爲你需要使用更具體的類型推斷 –

+0

自己的領域和方法進行操作查看實際用例的更新問題。也許是正確的:伴侶對象,希望隱式可以去掉額外的步驟... – virtualeyes

1

如果你只是想提取左右(我從你的例子是猜測),爲什麼不能用更少的解決你的問題代碼:

case class Pair[A, B](left: A, right: B) 

val pair = Pair(1, 2) 

val Pair(a, b) = pair 

println(a, b) 
+0

正確,這就是我在伴侶對象的想法中得到的結果(Pair實際上有其他幾個字段,所以它看起來更像是與案例類別的默認伴侶對象配對(a,b,_,_,_,_) 。在DSL對中,包含在實現map,flatMap和withFilter的包裝器中。因此,在理解中,我將有幾個對,我想不申請,並配對(a,b)< - tableA加入tableB on(...); Pair(c,d)< - tableC在(...)等上連接tableD並不像隱含的Tuple2解構 – virtualeyes

相關問題