2012-05-27 34 views
4

我有以下方法:方法採取隱式CanBuildFrom不適用於eta擴展?

def firstAndLast[CC, A, That](seq: CC)(implicit asSeq: CC => Seq[A], cbf: CanBuildFrom[CC, A, That]): That = { 
    val b = cbf(seq) 
    b += seq.head 
    b += seq.last 
    b.result 
} 

參見:Method taking Seq[T] to return String rather than Seq[Char]的理由。它的工作原理是在第一種情況下的魅力,但未能在第二編譯:

List("abc", "def") map {firstAndLast(_)} 
List("abc", "def") map firstAndLast 

,並提供:

error: No implicit view available from CC => Seq[A]. 
List("abc", "def") map firstAndLast 

任何想法如何提高這個聲明,以避免額外的包裝?好像ETA-擴大的問題

回答

1

雖然他們看起來很相似,這是不同的東西:

List("abc", "def") map {firstAndLast(_)} 
// { x => firstAndLast(x) } 

List("abc", "def") map firstAndLast 
// firstAndLast, if it happened to be a function 

現在請注意編譯器在第一種情況下如何輕鬆地輸入x。在第二種情況下,它試圖找出如何將(seq: CC)(implicit asSeq: CC => Seq[A], cbf: CanBuildFrom[CC, A, That])解釋爲Function1[String, ???],並且由於缺少大量信息(即類型參數)而失敗。

換言之,在第一種情況下,編譯器第一類型x,並且,因此,CC,然後試圖找出的其餘部分。在第二種情況下,編譯器試圖同時找出所有的類型參數。

1

不是一個完整的回答你的問題,但我只注意到這個工程(?):

List("abc", "def") map firstAndLast[String, Char, String] 

這則意味着該類型inferencer是有麻煩確定正確的類型參數firstAndLast,但我不知道如何解決它...