在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
是重复结构。
有办法做到这一点吗?
答案 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)
在您的特定情况下,返回类型取决于两个输入值n
和i
。这两个在编译时都是未知的(Scala是静态类型的!),这意味着编译器不会知道静态返回类型。由于种种原因,这显然很糟糕。
通常,您既不能定义递归类型,也不能utilize type inference for recursive methods。