1. ホーム
  2. scala

[解決済み] Scala における `#` 演算子の意味とは?

2022-05-24 06:41:13

質問

このブログでは、このようなコードを見かけます。 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] というのは見たことがありません。検索が難しいので(検索エンジンに無視される)、どなたかその意味を教えていただけませんか?

どのように解決するのですか?

それを説明するために、まず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.Ba2.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.