2

是否可以在 Scala 中表达如下递归类型定义?

type test = Either[List[test], Int]

更新

我的意图是表达如下功能:

def flatten[T](list: List[Either[List[T], T]]): List[T] = list flatMap {
    case Left(list)         => list
    case Right(element) => List(element)
}

但它接受任意深度的类似结构

4

2 回答 2

3

好吧,你可以这样做:

type test[T <: test[T]] = Either[List[T], Int]

scala> val x: test[Nothing] = Right(1)
x: test[Nothing] = Right(1)

scala> val y: test[test[Nothing]] = Left(List(x))
y: test[test[Nothing]] = Left(List(Right(1)))

scala> val z: test[_] = y
z: test[_] = Left(List(Right(1)))

不知道你为什么想要这个。

于 2012-08-29T03:40:44.983 回答
1

你不能有这样的递归类型别名。但是如果你创建一个单独的类,那就没问题了:

case class Test[+T](value: Either[List[Test[T]], T]) {
  def flatten: List[T] = value match {
    case Left(list)         => list.flatMap(_.flatten);
    case Right(element)     => List(element);
  }
}

(编程中最有趣的类实际上是递归的。)

您不能拥有type像您这样的递归别名的原因是编译器需要扩展type别名以判断某物是否具有该类型。但是递归类型别名像

type test = Either[List[test], Int]

扩展到无穷大:

Either[List[test], Int]
Either[List[Either[List[test], Int]], Int]
Either[List[Either[List[Either[List[test], Int]], Int]], Int]
...

对于类,这不会发生,因为类将递归值“包装”成具有明确定义的类型(如Test[T]本例中)。类型的“扩展”只有在您引用内部的东西时才会发生(value在这种情况下)。

于 2012-08-29T20:12:22.013 回答