2011-02-18 108 views
4

参考一previous answer of mine on stackoverflow这可以简化吗?

复杂的核心,在短短一个方法说明:

implicit def traversableToFilterOps[CC[X] <: Traversable[X], T] 
(xs: CC[T])(implicit witness: CC[T] <:< TraversableLike[T,CC[T]]) = 
    new MoreFilterOperations[CC[T], T](xs) 

有两个问题:

  1. 有没有什么办法让编译器的提示Map符合签名CC[X] <: Traversable[X]? 我期望它匹配为Traversable[Tuple2[_,_]]但这不会发生。最后,我不得不写第二种方法采取CC[KX,VX] <: Map[KX,VX],但那种感觉冗余

  2. witness: CC[T] <:< TraversableLike[T,CC[T]]也似乎是多余的给出的第一个类型参数,我的直觉是,这是由Traversable类型强制执行,必须始终适用于任何可能的子类或值X,所以应该没有理由明确要求它作为见证。

如果我测试这个在REPL使用一个存在的类型,那么编译器似乎同意我:

scala> implicitly[Traversable[X] <:< TraversableLike[X,Traversable[X]] forSome { type X }] 
res8: <:<[Traversable[X],scala.collection.TraversableLike[X,Traversable[X]]] forSome { type X } = <function1> 

有没有因此没有办法废除的样板?

+0

答案就在某处这里:https://gist.github.com/445874 – retronym 2011-02-18 10:16:06

回答

1

我是一个斯卡拉noob,所以请不要打我下来,如果这没有帮助。

假设这样的:

class MoreFilterOperations[Repr <% TraversableLike[T,Repr], T] (xs: Repr) {} 

会是这样的工作?

// t2fo is short for traversableToFilterOps 
implicit def t2fo[Repr <% TraversableLike[T, Repr], T](xs: Repr) = 
    new MoreFilterOperations[Repr, T](xs) 

// m2fo is short for mapToFilterOps 
implicit def m2fo[Repr <% Map[K, V] <% TraversableLike[(K,V), Repr], K, V] 
    (xs: Repr) = new MoreFilterOperations[Repr, (K, V)](xs) 

这应该工作,因为(根据这本书我有..编程斯卡拉,P264)与结合视图下面的方法定义:

def m [A <% B](arglist): R = ... 

它实际上是相同的,因为这方法定义:

def m [A](arglist)(implicit viewAB: A => B): R = ... 
+0

所以甚至不打扰检查`<:在隐式方法Traversable`,并削减直` <%TraversableLike`。我喜欢它...简单,对于这个特殊用例听起来似乎合理。它无助于回答隐含子类的更广泛的问题,但仍然是一个好主意。现在启动REPL并确认:) – 2011-02-20 15:21:48