2012-08-14 170 views
3

什麼是fs的一般類型?遞歸函數的返回類型

lazy val fs = List(2,3,4).zip(fs.tail) 

編譯器要求在編譯時設置它。

更新: 我要考慮的第二個項目歐拉問題的解決方案:

lazy val fs: Stream[Int] = 
     0 #:: 1 #:: fs.zip(fs.tail).map(p => p._1 + p._2) 

    fs.view.takeWhile(_ <= 4000000).filter(_ % 2 == 0).sum 

我只是想調試這些步驟

回答

5

我不認爲存在這樣形容它最精確的類型。當然,它不能被計算,所以實際的類型將是Nothing

如果我們忘記了隱式canBuildFrom,拉鍊的List[A]簽名會

def zip[B](l: List[B]) : List[(A,B)] 

與A =詮釋開始,很顯然,我們有一個List[(Int, B)],甚至沒有考慮到的參數zipfs.tail。如果我們添加這些知識,我們現在有List[(Int, (Int, B))],我們可以從那裏循環,您可以輸入List[(Int,(Int, (Int, _)))]並根據需要嵌套任意級別。

我相信沒有辦法在scala中表達最精確的類型(嵌套到無限)。無論如何,它是無人居住的,這種類型不包含任何價值,並且fs不能被計算。

+0

@ZoltanHamori我不相信這是真的。看到我的答案。 – 2012-08-14 17:30:49

+0

我同意你不能輸入它沒有,並意識到(我曾嘗試過,應該提到它)。我相信原因是Nothing雖然是任何類型的子類型,但沒有可以調用的成員(這使得它成爲一個相當特殊的子類型)。我的意思是輸入Nothing作爲永久循環(或溢出堆棧)的類型。我應該更精確。 – 2012-08-14 18:02:47

+0

Yeah'Nothing'是特殊的,但是不能將結果輸入到Nothing的原因是編譯器需要一個List,而Nothing不是一個List,它沒有任何意思。 )去做'Nothing'的成員。 – 2012-08-14 18:43:52

2

下編譯發生了什麼,但訪問fs生成因爲定義遞歸性質,所以StackOverflowError

lazy val fs:List[Product] = List(2,3,4).zip(fs.tail) 

如果我們想更具體的瞭解,我們可以做一些喜歡的類型:

lazy val fs:List[(Int, (Int, Product))] = List(2,3,4).zip(fs.tail) 

的typle不Nothing。由於以下不會編譯:發生

scala> lazy val fs:Nothing = List(2,3,4).zip(fs.tail) 
<console>:8: error: value tail is not a member of Nothing 
    lazy val fs:Nothing = List(2,3,4).zip(fs.tail) 

類似類型的錯誤,如果我們定義爲FS List[Nothing]List[(Int, Nothing)]等等等等,所以很明顯的表達的類型是Product一個List。現在,如果我們使用Stream,而不是我們可以做出的東西,不會導致運行時錯誤:

scala> lazy val fs:Stream[Any] = 0 #:: 1 #:: fs.zip(fs.tail).map(p => p:Any) 
fs: Stream[Any] = <lazy> 

scala> fs take 5 foreach println 
0 
1 
(0,1) 
(1,(0,1)) 
((0,1),(1,(0,1))) 
0

我不認爲這是可能在一種安全的方式,請看:

scala> lazy val fs=List(1,2,3).zip(fs.tail) 
<console>:7: error: recursive lazy value fs needs type 
     lazy val fs=List(1,2,3).zip(fs.tail) 
           ^

scala> lazy val fs:List[(Int,Int)]=List(1,2,3).zip(fs.tail) 
<console>:7: error: type mismatch; 
found : List[(Int, (Int, Int))] 
required: List[(Int, Int)] 
     lazy val fs:List[(Int,Int)]=List(1,2,3).zip(fs.tail) 

至少我看不出如何實現任何有用的結果。你有什麼打算?

在另一方面,我們可以這樣做:

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

scala> val fs = l.zip(l.tail) 
fs: List[(Int, Int)] = List((1,2), (2,3)) 

這是你想要的結果?