2013-03-13 74 views
3

好踢,所以我有这样的:添加成对差异泛型集合 - 隐分辨率不

implicit final class RichIterableLike[A, Repr <: IterableLike[A, Repr]](val it: Repr) 
    extends AnyVal { 
    def pairDiff[To](implicit num: Numeric[A], cbf: CanBuildFrom[Repr, A, To]): To = { 
    val b  = cbf(it) 
    val iter = it.iterator 
    if (iter.hasNext) { 
     var pred = iter.next() 
     while (iter.hasNext) { 
     import num.mkNumericOps 
     val succ = iter.next() 
     b += succ - pred 
     pred = succ 
     } 
    } 
    b.result() 
    } 
} 

这将编译,但不踢:

val stabs = IndexedSeq(1.0, 2.0, 3.0) 
stabs.pairDiff 

给出:value pairDiff is not a member of IndexedSeq[Double]

显式转换工作:

new RichIterableLike[Double, IndexedSeq[Double]](stabs).pairDiff 

...如何解决这个问题?


编辑

如果我申请的办法of this answer,它的工作原理:

implicit final class RichIterableLike[A, CC[~] <: Iterable[~]](val it: CC[A]) 
    extends AnyVal { 
    def pairDiff[To](implicit num: Numeric[A], cbf: CanBuildFrom[CC[A], A, To]): To = { 
    ... 
} 

但问题仍然存在,有什么关键的差别,使隐性查找踢在后一种情况。

回答

1

为了隐式查找工作,它需要AReprIterableLike要求链接)之间的链接。您将它作为参数传递,以便参数应输入为Repr[A]。这意味着你需要修改你的签名,以便它会是这个样子:

RichIterableLike[A, Repr[X] <: IterableLike[X, Repr[X]]](val it: Repr[A]) 

使用上述签名你说:

我有一个接受一个类型参数的对象,我会名称对象Repr,当你传递它,我也想捕获类型参数。我将命名该类型参数A。作为一个额外的条件,我希望Repr的类型符合IterableLike的签名

+0

“'IterableLike'要求链接” - 为什么?如何?它的签名是'Trait IterableLike [+ A,+ Repr]',对'Repr'没有限制,特别是不需要'Repr'自己拥有一个类型参数。 – 2013-03-15 14:07:34

+0

你是对的,我回到了文档,找不到它。在源文件中有记录:'@tparam Repr包含元素的实际集合的类型'。 “IterableLike”的所有实现都像这样使用它:'Seq [A]扩展IterableLike [A,Seq [A]](通常通过另一个特性,在这种情况下是SeqLike)。 – EECOLOR 2013-03-16 11:21:23