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 に答える