3 回答

TA貢獻(xiàn)1793條經(jīng)驗(yàn) 獲得超6個(gè)贊
對(duì)于理解將轉(zhuǎn)換為對(duì)mapor flatMap方法的調(diào)用。例如這個(gè):
for(x <- List(1) ; y <- List(1,2,3)) yield (x,y)
變成:
List(1).flatMap(x => List(1,2,3).map(y => (x,y)))
因此,第一個(gè)循環(huán)值(在本例中為L(zhǎng)ist(1))將接收f(shuō)latMap方法調(diào)用。由于flatMap在List返回另一個(gè)List,的的理解,結(jié)果當(dāng)然會(huì)是一個(gè)List。(這對(duì)我來(lái)說(shuō)是新的:因?yàn)槔斫獠⒉豢偸菍?dǎo)致信息流,甚至不一定會(huì)導(dǎo)致Seqs。)
現(xiàn)在,看看如何flatMap在中聲明Option:
def flatMap [B] (f: (A) ? Option[B]) : Option[B]
請(qǐng)記住這一點(diǎn)。讓我們看看如何將理解錯(cuò)誤(帶有的錯(cuò)誤Some(1))轉(zhuǎn)換為一系列map調(diào)用:
Some(1).flatMap(x => List(1,2,3).map(y => (x, y)))
現(xiàn)在,很容易看到該flatMap調(diào)用的參數(shù)是按要求返回a List而不是返回的東西Option。
為了解決問(wèn)題,您可以執(zhí)行以下操作:
for(x <- Some(1).toSeq ; y <- List(1,2,3)) yield (x, y)
這樣編譯就可以了。值得注意的是,Option它不是Seq通常所假定的的子類型。

TA貢獻(xiàn)1818條經(jīng)驗(yàn) 獲得超11個(gè)贊
一個(gè)容易記住的技巧,因?yàn)槔斫鈺?huì)嘗試返回第一個(gè)生成器的集合類型,在這種情況下為Option [Int]。因此,如果從Some(1)開(kāi)始,則應(yīng)該期望Option [T]的結(jié)果。
如果要獲取列表類型的結(jié)果,則應(yīng)從列表生成器開(kāi)始。
為什么有此限制,而不假定您總是需要某種順序?您可能會(huì)遇到需要返回的情況Option。也許你有一個(gè)Option[Int]你想要的東西結(jié)合起來(lái),得到一個(gè)Option[List[Int]],用下面的函數(shù)說(shuō):(i:Int) => if (i > 0) List.range(0, i) else None; 然后,您可以編寫此代碼,并在事情沒(méi)有“意義”時(shí)得到None:
val f = (i:Int) => if (i > 0) Some(List.range(0, i)) else None
for (i <- Some(5); j <- f(i)) yield j
// returns: Option[List[Int]] = Some(List(0, 1, 2, 3, 4))
for (i <- None; j <- f(i)) yield j
// returns: Option[List[Int]] = None
for (i <- Some(-3); j <- f(i)) yield j
// returns: Option[List[Int]] = None
實(shí)際上,如何擴(kuò)展理解力實(shí)際上是將類型的對(duì)象M[T]與函數(shù)組合(T) => M[U]以獲得類型的對(duì)象的相當(dāng)通用的機(jī)制M[U]。在您的示例中,M可以是Option或List。通常,它必須是相同的類型M。因此,您不能將Option與List結(jié)合使用。有關(guān)可能存在的其他情況的示例M,請(qǐng)查看此特征的子類。
為什么結(jié)合List[T]與(T) => Option[T]工作雖然當(dāng)你開(kāi)始與列表?在這種情況下,庫(kù)在有意義的地方使用更通用的類型。因此,您可以將List與Traversable結(jié)合使用,并且存在從Option到Traversable的隱式轉(zhuǎn)換。
底線是:考慮要讓表達(dá)式返回哪種類型,并以該類型作為第一個(gè)生成器開(kāi)始。如有必要,將其包裝為該類型。
- 3 回答
- 0 關(guān)注
- 613 瀏覽
添加回答
舉報(bào)