2011-12-09 36 views
3

我用這給了我下面的(關係可以被隱式轉換爲節點)庫:我自己用如何讓這個Scala隱式轉換工作?

class Relation[A,B] 
class Node[A,B](r: Relation[A,B]) 
implicit def relation2node[A,B](r: Relation[A,B]) = new Node(r) 

我伸出關係:

class XRelation[A] extends Relation[A,Int] 

關係/ XRelations是爲了被繼承:現在

class User extends XRelation[Int] 

,我也定義自己的輔助方法,如GET,設計了一個轉換爲節點的任何節點和任何工作:

class Helper[A,B](n: Node[A,B]) { def GET {} } 

// note: this is the only way I know of to make the next example work. 
implicit def xx2node2helper[A,B,C[_,_]](x: C[A,B])(implicit f: C[A,B] => Node[A,B]) = new Helper(x) 

所以這個例子的工作原理:

​​

如果我再添隱式轉換:

// don't understand why this doesn't work for the previous example 
// but works for the next example 
implicit def x2node2helper[A,B,C](x: C)(implicit f: C => Node[A,B]) = new Helper(x) 

我也可以做如下的轉換工作:

new XRelation[Int]().GET 

但是這不起作用:

new User().GET 

可悲的是,失敗:

error: No implicit view available from Sandbox3.User => Sandbox3.Node[A,B] 

任何人都可以做這一切的意識,解釋如何得到最後一個例子來工作?提前致謝。

更新:我知道你剛剛從Relation介紹隱式轉換,但我要求(1)找出如何做到這一點,而不必從每一個類型可能可能隱式轉換到節點介紹implicits (2)鞏固我對含義的理解。

回答

4
implicit def nodeLike2Helper[R, C <: R](r:C)(implicit f: R => Node[_,_]) = { 
    new Helper(r) 
} 

正如錯誤信息表明,User沒有隱式轉換Node 。但它是超級超級關係。所以你只要給出正確的界限來輸入參數。

FYI,存在用於視圖邊界語法糖<%,所以上述代碼可以更短:

implicit def nodeLike2Helper[R <% Node[_,_], C <: R](r:C) = { 
    new Helper(r) 
} 
1

當檢查用戶是否匹配類型模式C[_,_]時,scala分辨率只會深入一個超類。您可以通過取消以下代碼中的模式來解決此問題。

implicit def x2node2helper[A,B](x: Relation[A,B])(implicit f: Relation[A,B] => Node[A,B]) = new Helper(x) 

如果隱含relation2node是在範圍爲x2node2helper的定義,那麼就可以寫成

implicit def x2node2helper[A,B](x: Relation[A,B]) = new Helper(x) 
+0

謝謝,但我要求(1),計算出如何做到這一點,而無需引入可能隱式轉換爲節點的每種類型的蘊涵,以及(2)真正鞏固我對隱含的理解。澄清我的問題。 – Yang