2017-11-03 5 views
4

私はFoundations of path dependent typesを読んでいます。最初のページで、右側の列にそれが書かれている:型メンバーを持つオブジェクト:Scalaのオブジェクトとモジュールシステムは何ですか? (パス依存型のOdersky論文を理解しようとしています)

Our motivation is twofold. First, we believe objects with type members are not fully understood. It is not clear what causes the complexity, which pieces of complexity are essential to the concept or accidental to a language implementation or calculus that tries to achieve something else. Second, we believe objects with type members are really useful. They can encode a variety of other, usually separate type system features. Most importantly, they unify concepts from object and module systems, by adding a notion of nominality to otherwise structural systems.

は、誰かが「オブジェクトモジュール対」システムはどういう意味/明確に説明してもらえますか?

または一般に、

​​

は何を意味するのでしょうか?

どのような概念ですか?どこから ?

オブジェクト名/値のNominality? タイプの構造は?それとも別の方法ですか?

ここのメンバーはどこに属していますか?モジュールシステムに?オブジェクトシステム?どうやって?どうして?

EDIT:

どのようにこの統一は、パス依存型に関連していますか?この統一が起こることを彼らが認めているようです(型メンバーを持つオブジェクト)。そうですか ? はいの場合、どうですか?

簡単な例を教えてください。 (つまり、パス依存型は、モジュールやオブジェクトシステムの統一を可能対我々はパス依存型を持っていないならば、なぜ統合が起こる可能ではないでしょうか?)

EDIT 2:

紙から:

To make any use of type members, programmers need a way to refer to them. This means that types must be able to refer to objects, i.e. contain terms that serve as static approximation of a set of dynamic objects. In other words, some level of dependent types is required; the usual notion is that of path-dependent types.

だから、これまでのところ(ジェスパーの答えの助けを借りて)私の理解:

は、部分的に上記のこの段落は、上記の質問のいくつかに答えます。主なのは、型メンバーを持つオブジェクトを持ち、オブジェクトが動的/ランタイムに依存するが型は静的(コンパイル時に定義される)なので、その型依存型が必要なように思えます。コンパイル時にこれらの型メンバーが明確に定義されないためです。

パス依存型は、コンパイル時に型メンバに至るパスを固定することによって(コンパイル時にオブジェクトがすでに認識されていることを要求することによって)、パスがオブジェクトコンパイル時にそれらのオブジェクトが既に固定されている場合、それらの型メンバーはコンパイル時にも明確な意味を持つことができます。

+0

PS:PDFはこちらからもダウンロードできます:http://lampwww.epfl.ch/~amin/dot/fpdt.pdf – jhegedus

答えて

3

私はあなたの質問が何であるか完全に理解していませんが、私はそれを刺すでしょう。私は、主にML style modulesを参照していると思います。ここで、シグネチャはScalaの特性に対応し、構造はScalaのオブジェクトに対応します。 Scalaはレコードの値、オブジェクト、モジュールのコンセプトを統一しています。ほとんどの言語(ML、Rustなど)は別の概念です。主な利点は、Scalaのモジュール/オブジェクトを通常の関数引数として渡すことができることです(MLでは特別なファンクタを使用する必要があります)。

MLでは、モジュールはその構造(Scalaの構造型に似ています)に基づいて署名(Scalaの特性)との互換性がチェックされますが、Scalaではモジュールは名前(名目型)によって特性を実装する必要があります。したがって、たとえ2つのモジュール/オブジェクトがScalaで同じ構造を持っていても、スーパータイプの階層によっては互いに互換性がないかもしれません。

Scalaの型メンバーに関する本当に強力な機能は、型の安全な方法でそれを行う限り、その型メンバーの正確な型がわからなくても、特性を使用できることです(これは例えば、)MLモジュールでも可能:

trait A { 
    type X 
    def getX: X 
    def setX(x: X): Unit 
} 

def foo(a: A) = a.setX(a.getX) 

fooではScalaのコンパイラはa.Xの正確な型が、それでもコンパイラが安全であることを知っている方法で使用することができるタイプの値を知りません。これは例えばin Rustではありません。

Scalaコンパイラの次のバージョンであるDottyは、参考文献に記載されている理論に基づいています。サブタイプ、特性、型メンバーと組み合わせたこのモジュールとオブジェクトの統合は、Scalaがユニークで非常に強力な理由の1つです。

EDIT:

def bar(a: A, b: A) = a.setX(b.getX) 

これは、コンパイルエラーが発生します:

error: type mismatch; 
found : b.T 
required: a.T 
    def foo(a: A, b: A) = a.setX(b.getX) 
           ^
経路依存型がのは、上記で例を展開させ、Scalaのモジュール/対象システムの柔軟性が向上する理由ビットを拡張します

と正しくはa.Tb.Tが異なるタイプに解決できるためです。

def bar(a: A)(b: A { type X = a.X }) = a.setX(b.getX) 

またはタイプパラメータを追加します:あなたは、パス依存型の使用して、それを修正することができ、そう

def bar[T](a: A { type X = T }, b: A { type X = T }) = a.setX(b.getX) 

をパス依存型の型パラメータのいくつかの必要がなくなり、また、私たちは実存表現することができます(型メンバーの代わりに型パラメーターがある場合は、A[_]またはA[T] forSome { type T }に対応します)。

+0

なぜ統一を得るために名目を追加する必要があるのでしょうか? 。構造的なタイピングも同様に機能しませんか? – Bergi

+0

答えに感謝します。統一はパスに依存するタイプと何が関係しているのだろうか? – jhegedus

+0

パスに依存しないタイプがあればどうなるでしょうか?この統一はまだ可能だろうか?この統一についての簡単な例と、パス依存型がそれを可能にする方法を教えてください。 – jhegedus

関連する問題