2010-11-25 60 views
3

例如,我有以下的是串接beginings和結局產生級聯的所有可能的變體結果函數:這種奇怪的類型[T *]

def mixer1(begin: String, beginings: String*)(end: String, endings: String*) = 
    for (b <- (begin +: beginings); e <- (end +: endings)) yield (b + e) 

其實什麼功能呢是不是impotant,我想重寫它是這樣的:

def mixer2(begin: String, beginings: String*):Function2[String, Seq[String], Seq[String]] = { 
    return new Function2[String, Seq[String], Seq[String]] { 
     def apply(end:String, endings:Seq[String]) = for(b <- (begin +: beginings); e <- (end +: endings)) yield b+e 
    } 
    } 

顯然,第二個是行不通的預期,因爲申請的第二個參數的類型是序列[字符串]而不是字符串*(howewer他們都編譯成序列[字符串]):

scala> mixer1("a","b")("c","d") 
res0: Seq[java.lang.String] = ArrayBuffer(ac, ad, bc, bd) 

scala> mixer2("a","b")("c","d") 
<console>:10: error: type mismatch; 
found : java.lang.String("d") 
required: Seq[String] 
     mixer2("a","b")("c","d") 

我該如何(如果可以)重新定義mixer2功能?

+0

只想了很短的時間,我認爲這應該是實際工作。你可以問#scala或者看看你是否在bug追蹤器中發現了這個問題。 – soc 2010-11-25 11:29:45

回答

3

試試這個方法:

def mixer2(begin: String, beginings: String*) = { 
    new ((String, String*) => Seq[String]) { 
     def apply(end: String, endings: String*) = for(b <- (begin +: beginings); e <- (end +: endings)) yield b+e 
    } 
} 

我們用mixer2類型推斷,以獲得正確的類型。這意味着return必須刪除,但沒關係,因爲它是不必要的(並且,通常不建議在Scala上)。大訣竅是使用A => B語法糖Function能夠使用String*。然後按預期方式更改apply

2

你可以去簡單的方法:

def mixer2 = mixer1 _ 
0

如你的榜樣,你可以做到這一點

implicit def toSeq[T](x: T): Seq[T] = List(x) 

但是,當涉及到更多的參數,如

mixer2("a","b")("c","d","e")

儘管存在從Array [T]到Seq [T]的隱式轉換,似乎沒有合適的解決方案。由於T *是語法糖果,因此(「c」,「d」,「e」)將被視爲3個參數。編譯器無法識別哪一個組成陣列。

所以我想知道你的實際情況是什麼,這個例子看起來很奇怪。 如果你只想要一部分功能,@ Debilski的解決方案是一個好方法。

0

即使沒有命名中間返回類型,也可以轉義。

def mixer2(begin: String, beginings: String*) = new { 
    def apply(end: String, endings: String*) = 
    for (b <- (begin +: beginings); e <- (end +: endings)) yield b+e 
} 

人們會試圖告訴你,這涉及反思。令人驚訝的是,事實並非如此。

+0

你可以擴展如何不使用反射?它看起來像我的新手眼睛(在2.8.0)。 – 2010-11-29 14:54:01