Scalaのパス依存型とはどういう意味ですか?


125

Scalaにはパスに依存する型があると聞きました。これは内部クラスと関係がありますが、これは実際に何を意味し、なぜ私は気にするのですか?


2
@Michel-私はPDTが何であるかさえ知っています。SOが答えで豊かになることを期待していました!
oxbow_lakes 2010

1
PDTについてch12を読んだ後の簡潔な答えがあるといいのですが
スタッカー

回答:


165

私のお気に入りの例:

case class Board(length: Int, height: Int) {
  case class Coordinate(x: Int, y: Int) { 
    require(0 <= x && x < length && 0 <= y && y < height) 
  }
  val occupied = scala.collection.mutable.Set[Coordinate]()
}

val b1 = Board(20, 20)
val b2 = Board(30, 30)
val c1 = b1.Coordinate(15, 15)
val c2 = b2.Coordinate(25, 25)
b1.occupied += c1
b2.occupied += c2
// Next line doesn't compile
b1.occupied += c2

したがって、のタイプはCoordinate、インスタンスBoard化元のインスタンスに依存します。これで達成できるすべての種類のものがあり、型のみではなく値に依存する一種の型安全性を提供します。

これは依存型のように聞こえるかもしれませんが、より制限されています。たとえば、のタイプはoccupiedの値に依存しますBoard。上記では、最後の行はのタイプがでc2あるため機能しませんがb2.CoordinateoccupiedのタイプはSet[b1.Coordinate]です。同じタイプの別の識別子を使用できるためb1、そのタイプに関連付けられている識別子 ではないことに注意してくださいb1。たとえば、次の作品:

val b3: b1.type = b1
val c3 = b3.Coordinate(10, 10)
b1.occupied += c3

2
答えは+1。最後の文は紛らわしいことに気づきました。「タイプセーフではなく、値のみに依存するタイプセーフ」と言っています。私には、これは依存型のように聞こえますが、パス依存型は値自体には依存しません。それもまた混乱していると思いますか?
マシューファーウェル

4
@マシュー私はあなたの言っていることを理解していますが、パス依存型、依存型に通常関連付けられている柔軟性を提供していなくても、値に依存しています。
ダニエルC.ソブラル2011

1
まさに、それが私の言いたいことです。最初に、型はb1 / b2ではなく、コンストラクターに渡された値に依存することを読みました。私はそれを理解しましたが、それを取得するには数回の読み取りが必要でした。
マシューファーウェル2011

3
最も簡単な説明は、パスに依存する型は、クロージャーを備えた単なるクラスであり、関数がスコープから変数をバインドする方法とまったく同じです。
polkovnikov.ph 2014

1
しかし、おそらくこの類推には1つの基本的な違いがあります。1つのバインディングは実行時に(クロージャの場合)行われ、もう1つのバインディングはコンパイル時に行われます(パス依存型の場合)。
jhegedus
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.