我正在使用一个给我以下内容的库(关系可以隐式转换为节点):
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]
现在,我还定义了自己的Helper方法,如GET,旨在与任何Node和任何转换为Node的东西一起使用:
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)
所以这个例子有效:
new Relation[Int,Int]().GET
如果我添加另一个隐式转换:
// 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)弄清楚如何做到这一点,而不必引入每个单词的含义可能隐式转换为Node的类型,以及(2)巩固我对implicits的理解。
答案 0 :(得分:4)
implicit def nodeLike2Helper[R, C <: R](r:C)(implicit f: R => Node[_,_]) = {
new Helper(r)
}
正如错误消息所示,User
没有隐式转换为Node
。但它是超级超级联盟。所以你只需给出正确的界限来输入参数。
仅供参考,视图边界有一个语法糖<%
,因此上面的代码可以更短:
implicit def nodeLike2Helper[R <% Node[_,_], C <: R](r:C) = {
new Helper(r)
}
答案 1 :(得分:1)
在检查User是否与类型模式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)