行多態性と有界多態性の違いは?


7

私は最近、Brian McKennaが行のポリモーフィズムを説明しているこのブログ投稿を見つけました。これは私にとっては素晴らしいアイデアのように見えましたが、その後、制限付きパラメトリック多態性のようなひどいにおいがすることに気付きました。

行ポリモーフィズムの場合:

sum: {x: int, y: int | rho} -> int
function sum r = r.x + r.y

制限付きパラメトリック多態性:

sum: forall a <: {x: int, y: int}. a -> int
function sum r = r.x + r.y

誰かがこれらの2つのアプローチの多型性の違いを明確にできますか?


2
let f x = x with {sum: x.a + x.b}両方で入力してみましたか?私が正しく理解していれば、行多型は、あなたが余分なフィールドがであるものは何でも維持することができますxが、有界パラメトリック多型は、あなたがそのタイプを持っていると言いたいと思いませんのでforall a <: {x: int, y: int}. a -> a_with_a_new_field_sum、私はあなたが表現できるとは思いませんa_with_a_new_field_sum
xavierm02 2017年

うーん、それはwith構造の正確なセマンティクスに依存すると思います。それは記事に記載されていなかったので、混乱を招くので避けた。
gardenhead 2017年

1
まあ(私はそう思います)行のポリモーフィズムの表現力は、「および他の属性の束」の名前を取得したという事実から来ています。したがって、関数の型付けで他の属性の束を表す型変数を使用しない場合、おそらく実際には行のポリモーフィズムは必要ありません。forgetレコードを取得し、そのフィールドの1つを削除する演算子を使用することもできます。次に、と入力するにはfun r -> forget x of r、おそらく行のポリモーフィズムも必要です。
xavierm02 2017年

システムについての詳細がなければ、当然のことながら、限定されたポリモーフィズムがより一般的であることを除いて、それらはほぼ同等であると言えます。通常、行の型指定は、行の結合や行の制限など、行に対するいくつかの型レベルの操作も意味します。私はこの答えで同様のことを言います
Derek Elkinsが

回答:


3

したがって、いくつかの違いがあります。

  • 行のポリモーフィズムでは、名前にをバインドしたので、他の場所で使用できます。たとえば、は行ポリモーフィズムで表現できますが、境界ポリモーフィズムを純粋に使用することはできません。同様に、フィールドの削除を次のように表現することもできます。これは完全に有効な行多相型ですが、サブタイピングにはこれを表現する方法がありません。ρforall rho . rho -> {x : int | rho}forall rho .{x : int | rho} -> rho

    行のポリモーフィズムでは、この方法でフィールドを追加および削除できるため、通常は「スタック」セマンティクスで機能し、同じ名前の新しいフィールドが追加されると古いフィールドがシャドウされます。

  • 境界付きサブタイピングは、サブタイピングを使用します。したがって、行のポリモーフィズムでx : {x : int, y : int}は、型の関数に引数を与えることはできません{x : int} ->int。しかし、限定されたサブタイピングを持つほとんどのシステムには、非多態的なサブタイピングもあり、ほとんどのシステムにはがあるため、これが可能になります{x : int} <: {x : int, y : int}

境界付きサブタイピングは、より正確で柔軟になる傾向があり、行ポリモーフィズムの「スタック」セマンティクスはそれほど発生しません。しかし、推論は行のポリモーフィズムの方がはるかに簡単であり、タイプアノテーションがない場合(たとえば、Elmの場合)に機能します。通常、サブタイプが存在する場合は当てはまりません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.