2010-05-20 30 views
2

在下面的代碼片段中 - 爲什麼我必須爲Nil提供類型註釋?爲什麼Scala的類型推理器無法解決這個問題?

Welcome to Scala version 2.8.0.RC2 (OpenJDK Server VM, Java 1.6.0_18). 
Type in expressions to have them evaluated. 
Type :help for more information. 

scala> List(Some(1), Some(2), Some(3), None).foldLeft(Nil)((lst, o) => o match { case Some(i) => i::lst; case None => lst })   
<console>:6: error: type mismatch; 
found : List[Int] 
required: object Nil 
    List(Some(1), Some(2), Some(3), None).foldLeft(Nil)((lst, o) => o match { case Some(i) => i::lst; case None => lst }) 
                          ^

scala> List(Some(1), Some(2), Some(3), None).foldLeft(Nil:List[Int])((lst, o) => o match { case Some(i) => i::lst; case None => lst }) 
res1: List[Int] = List(3, 2, 1) 

回答

3

的問題是,Nil是延伸List的對象。這意味着Nil.typeList的子類,因此,foldLeft的累加器的類型將爲Nil.type

這是我希望Scala嘗試了一點(或很多,無論它需要:)更難得到一個更好的類型推斷的地方。

0

你可以做這樣的

private def removeNone[A](xs:List[Option[A]]) = { 
    xs.filter(_.isInstanceOf[Some[_]]).map(_ match { 
     case Some(t) => t 
     case _ =>().asInstanceOf[A] //can't happen, needed to avoid warning 
    }) 
} 

雖然這可能沒有直接回答你的問題避免麻煩,我幾個小時前寫了這個功能,並認爲這不能傷害分享。如果您不介意發出警告,您可以省略第二種情況。

我還發現地圖和過濾器的組合比摺疊更容易閱讀。我只嘗試在必要時使用摺疊。

相關問題