このブログでこのコードを見つけました:Scala での型レベルプログラミング:
// define the abstract types and bounds
trait Recurse {
type Next <: Recurse
// this is the recursive function definition
type X[R <: Recurse] <: Int
}
// implementation
trait RecurseA extends Recurse {
type Next = RecurseA
// this is the implementation
type X[R <: Recurse] = R#X[R#Next]
}
object Recurse {
// infinite loop
type C = RecurseA#X[RecurseA]
}
#
コード内に見たことのない演算子がありますR#X[R#Next]
。検索が難しい(検索エンジンでは無視される)ので、その意味を教えていただけますか?
ベストアンサー1
これを説明するには、まず Scala のネストされたクラスについて説明する必要があります。次の簡単な例を考えてみましょう。
class A {
class B
def f(b: B) = println("Got my B!")
}
では、これを使って何か試してみましょう:
scala> val a1 = new A
a1: A = A@2fa8ecf4
scala> val a2 = new A
a2: A = A@4bed4c8
scala> a2.f(new a1.B)
<console>:11: error: type mismatch;
found : a1.B
required: a2.B
a2.f(new a1.B)
^
Scalaでクラス内に別のクラスを宣言する場合、各インスタンスそのクラスにはそのようなサブクラスがあります。言い換えれば、クラスは存在しませんが、クラスはA.B
存在し、それらはa1.B
a2.B
違う上記のエラー メッセージが示しているように、クラスです。
それが理解できなかった場合は、パス依存型を調べてください。
では、#
特定のインスタンスに限定することなく、このようなネストされたクラスを参照することができます。言い換えると、 はありませんA.B
が、 はあります。これは、のネストされたクラスA#B
を意味します。B
どれでものインスタンスA
。
上記のコードを変更すると、これが実際に機能することを確認できます。
class A {
class B
def f(b: B) = println("Got my B!")
def g(b: A#B) = println("Got a B.")
}
試しにやってみると:
scala> val a1 = new A
a1: A = A@1497b7b1
scala> val a2 = new A
a2: A = A@2607c28c
scala> a2.f(new a1.B)
<console>:11: error: type mismatch;
found : a1.B
required: a2.B
a2.f(new a1.B)
^
scala> a2.g(new a1.B)
Got a B.