返回类型的递归函数

时间:2012-08-14 12:02:27

标签: scala

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

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

3 个答案:

答案 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))

这是你想要的结果吗?