Scala如何处理递归返回类型?

时间:2015-09-05 19:31:54

标签: scala recursion

在OCaml中有一个名为'rectype'的东西,它允许递归返回类型。为了说明我的意思,这是一种具有这种类型的方法:

def foo(n: Int)(i: Int): ??? = {
  val m = n + i
  (foo(m), m)
}

问题是;你在???的位置放了什么?查看代码,您会认为它类似于:

Int => Int => (Int => (Int => (Int => (Int => ... , Int)

为什么呢?因为foo(m)的类型是Int => (Int => rep, Int),其中元组中的rep是重复结构。

有办法做到这一点吗?

2 个答案:

答案 0 :(得分:7)

当然,Scala具有递归类型(但可能不是您正在寻找的类型)。以List为例(缩略为相关部分):

sealed abstract class List[+A] ...

final case class ::[B](head: B, tl: List[B]) extends List[B] ...

object Nil extends List[Nothing] ...
使用cons List(1, 2, 3)从多个列表递归定义

::

1 :: 2 :: 3 :: Nil

或没有中缀符号:

::(1, ::(2, ::(3, Nil)))

假设你可以用这种方式表示类型。但请注意,您必须自己定义类型:

sealed abstract class Inf[A]

case class Func[A](_1: A => Inf[A], _2: A) extends Inf[A] with Product2[A => Inf[A], A]

object Identity extends Inf[Nothing]

def foo(n: Int)(i: Int): Inf[Int] = {
    val m = n + i
    Func(foo(m) _, m)
}

或者更具体一点:

def foo(n: Int)(i: Int): Func[Int] = {
    val m = n + i
    Func(foo(m) _, m)
}

scala> val f = foo(5)(3)
f: Func[Int] = Func(<function1>,8)


scala> f._1(10)
res8: Inf[Int] = Func(<function1>,18)

答案 1 :(得分:0)

在您的特定情况下,返回类型取决于两个输入值ni。这两个在编译时都是未知的(Scala是静态类型的!),这意味着编译器不会知道静态返回类型。由于种种原因,这显然很糟糕。

通常,您既不能定义递归类型,也不能utilize type inference for recursive methods