簡體   English   中英

Scala-Flatmap一系列選項和可遍歷

[英]Scala - Flatmap a Seq of Options and Traversable

考慮在某些情況下匹配編寫的flatMap。 例如:

list.flatMap( v =>
    v match {
        case Cond1 => if(something) Some(Int) else None
        //..Other conditions yielding Option[Int]
        case CondN => if(somethingelse) Seq(Int) else Seq()
    })

但是,這不會編譯。 如果seq是Option [Int]的全部或Seq [Int]的全部,則flatMap將起作用。 但如果Seq是選項和Seq的混合,則不是。 為什么會有這樣的限制? 這是否解決了我目前無法想到的特殊歧義。

EDIT1從REPL添加代碼段

scala> val a = Seq(Option(1), Seq(2,3))
a: Seq[Equals] = List(Some(1), List(2, 3))

scala> val b = Seq(Seq(1), Seq(2,3))
b: Seq[Seq[Int]] = List(List(1), List(2, 3))

scala> a.flatMap(x=>x)
<console>:9: error: type mismatch;
 found   : Equals
 required: scala.collection.GenTraversableOnce[?]
              a.flatMap(x=>x)
                           ^

scala> b.flatMap(x=>x)
res24: Seq[Int] = List(1, 2, 3)

EDIT2在Filippo回答后,我在REPL中嘗試了以下代碼,並且可以正常工作。

scala> val options = Seq("opt1", "opt2")
options: Seq[String] = List(opt1, opt2)

scala> options.flatMap( x => 
     |      x match {
     |      case "opt1" => Some(1)
     |      case "opt2" => Seq(2,3)
     |      case _ => None
     |      })
res27: Seq[Int] = List(1, 2, 3)

在每種情況下,分辨率有何不同? 更重要的是,當我映射而不是flatMap時,結果與我創建的Seq a相同。

scala> options.map( x => 
 |      x match {
 |      case "opt1" => Some(1)
 |      case "opt2" => Seq(2,3)
 |      case _ => None
 |      })
res28: Seq[Equals] = List(Some(1), List(2, 3))  

OptionGenTraversableOnce但是scala在這里需要一些幫助:

  val a: Seq[TraversableOnce[Int]] = Seq(Option(1), Seq(2,3))
  a.flatMap(x=>x)

  res0: Seq[Int] = List(1, 2, 3)

在添加問題后進行編輯

我認為,如果序列的類型是您期望的那種,那么一切都歸結為傳遞給flatMap的函數。 如果scala在開始序列為Seq[A]時無法確定函數為(A) => Traversable[A] Seq[A] ,我認為我們應該使某些類型明確。

現在,回到您的第一個示例,我將其重構為:

list.flatMap {
  case Cond1 if something     => Seq(Int)
  case CondN if somethingelse => Seq(Int)
  case _                      => Seq()
}

毫無疑問,scala現在能夠正確推斷類型。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM