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

我只是想调试在这些步骤中发生的事情

4

3 回答 3

5

我认为没有最精确的类型可以描述它。当然,它不能被计算,所以实际的类型是Nothing.

如果我们忘记隐含的 canBuildFrom,则 zip in 的签名List[A]将是

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

从 A = Int 开始,很明显我们有一个List[(Int, B)],甚至没有考虑到zipis的论点fs.tail。如果我们添加该知识,我们现在拥有List[(Int, (Int, B))]并且可以从那里循环,您可以键入它List[(Int,(Int, (Int, _)))]并嵌套任意多个级别。

我相信没有办法在 scala 中表达最精确的类型(嵌套到无限)。反正它是无人居住的,这个类型不包含任何值,fs 也无法计算。

于 2012-08-14T12:28:27.803 回答
2

以下编译,但由于定义 recursize 性质,访问会fs生成 a 。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)

类型不是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)]所以很明显,表达式的类型是 a Listof Product。现在如果我们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)))
于 2012-08-14T12:27:56.490 回答
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))

这是你想要的结果吗?

于 2012-08-14T12:30:52.377 回答