2013-05-15 62 views
1

我似乎無法理解爲什麼我的程序需要這種情況下的顯式參數類型。使用下面的方法:缺少泛型掃描的參數類型

trait DistTraversableLike[+T, +Repr] 
    extends DistTraversable[T] { 
    self: Repr => 
... 
    def scan1lD[T1 >: T, That](assOp: (T1, T1) => T1)(implicit bf: CanBuildFrom[Repr, T1, That]): That = { 
    val b = bf(this) 
    for (x <- group.prefixSumSeq(part, assOp)) 
     b += x 
    b.result 
    } 
} 

我嘗試使用它在一個特定的實現,像這樣:

val x:DistSeq[Int] = DistSeq((0 until worldSize): _*) 
val scan = x.scan1lD(_+_) 

這產生以下錯誤消息:

Multiple markers at this line 
    - missing parameter type for expanded function ((x$1: <error>, x$2) => x$1.$plus{<null>}(x$2{<null>}){<null>}) 
    {<null>} 
    - missing parameter type for expanded function ((x$1, x$2) => x$1.$plus{<null>}(x$2{<null>}){<null>}){<null>} 
    - missing parameter type for expanded function ((x$1: <error>, x$2) => x$1.$plus(x$2)) 
    - missing parameter type for expanded function ((x$1, x$2) => x$1.$plus(x$2)) 

組是混合的特質使用來自FooParOps-trait(原型實施)的方法:

def prefixSumSeq[T](part: Seq[T], combiner: (T, T) => T): Seq[T] = { 
    implicit val srlz = getSerializerFor(part) 
    var result = part.head 
    var msg = part.reduce(combiner) 
    for (i <- 0 until log2i(size)) { 
     val partner = localRank^math.pow(2, i).toInt 
     send(partner, msg) 
     val number: T = rcv(partner) 
     msg = combiner(msg, number) 
     if (partner < localRank) result = combiner(number, result) 
    } 
    return (part.tail).scanLeft(result)(combiner) 
    } 

partDistTraversable[+T],並定義爲def part: Seq[T]

我不太明白爲什麼明確的參數都是必須的?請告訴我是否需要更多信息。目前該計劃相當複雜。

+0

scan1lD for循環中的變量'group'和'part'是什麼? –

+0

我加了一個更全面的解釋 – Felix

+0

我試着簡化了你的問題,但最後我做了很多改變,只是爲了得到編譯好的東西......如果你更明確的話,你會得到相同的編譯錯誤, 'x.scan1lD((x:Int,y:Int)=> x + y)'?一個問題是,它不能隱式地解決正確的'CanBuildFrom',因爲它不知道'That'的類型? –

回答

0

我能想到的唯一的事情是很醜陋的(但可以接受):

implicit class Scan1lDable[T, Repr](v: DistTraversableLike[T, Repr]) { 
    def scan1lD[That](op: (T,T) => T) // Note: no T1 
        (implicit bf: CanBuildFrom[Repr, T, That]): That = { 
    // snip 
    } 
} 

現在,您的示例將工作,但下面不會:

class A 
class B extends A 

def op(x: A, y: B) = x 

val x: DistTraversableLike[B, ...] = ... 
x.scan1lD(op _) 

但這會:

(x: DistTraversableLike[A, ...]).scan1lD(op _) 

所以我們增加一個便捷方法DistTraversableLike

trait DistTraversableLike[+T, +Repr] 
    extends DistTraversable[T] { 
    self: Repr => 

    def lower[S >: T]: DistTraversableLike[S, Repr] = this 

} 

,現在可以撥打:

x.lower[A].scan1lD(op _) 

誠然,這是十分可怕的,但可能不必指定的方法類型更易於接受。