fs
的一般类型是什么?
lazy val fs = List(2,3,4).zip(fs.tail)
编译器要求在编译时设置它。
更新: 我想考虑第二个项目Euler问题的解决方案:
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
我只是想调试在这些步骤中发生的事情
答案 0 :(得分:5)
我认为没有最精确的类型可以描述它。当然,它无法计算,因此实际类型为Nothing
。
如果我们忘记了隐含的canBuildFrom,List[A]
中zip的签名将是
def zip[B](l: List[B]) : List[(A,B)]
从A = Int开始,很明显我们有List[(Int, B)
],甚至没有考虑zip
的参数是fs.tail
。如果我们添加了这些知识,我们现在有List[(Int, (Int, B))]
并且我们可以从那里循环,您可以键入它List[(Int,(Int, (Int, _)))]
并根据需要嵌套多个级别。
我相信没有办法在scala中表达最精确的类型(嵌套到无限)。无论如何,它没有人居住,这种类型不包含任何值,并且无法计算fs。
答案 1 :(得分: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)]
等等,则会发生类似的错误。很明显,表达式的类型是List
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)))
答案 2 :(得分: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))
这是你想要的结果吗?