10

Haskell には構造型付けがあると説明されているのを聞いたことがあります。私が理解しているように、レコードは例外です。たとえば、 とは名目上フィールドが異なるだけであるにもかかわらず、fooを何かの型で呼び出すことはできません。HRec2HRecHRec2

data HRec = HRec { x :: Int, y :: Bool }
data HRec2 = HRec2 { p :: Int, q :: Bool }

foo :: HRec -> Bool

レコードを含むすべてに構造型付けを拡張することを拒否する理由はありますか?

レコードに対しても構造型付けを持つ静的型付け言語はありますか? これについて、静的に型付けされたすべての言語全般について読むことができる議論はありますか?

4

4 に答える 4

16

Haskell には構造型がありますが、構造型はありません。これは今後も変わらないでしょう。*

交換可能な引数として、名目上は異なるが構造的に類似した型を許可することを拒否することを、型安全性と呼びます。それは良いことです。Haskell には、名目上だけ異なる型を提供する newtype 宣言さえあり、型の安全性を強化することができます。型の安全性は、実行時にバグを許可するのではなく、バグを早期に発見する簡単な方法です。

型クラスを介したアドホック ポリモーフィズム (事実上、プログラマーが宣言した機能の等価性) を含む amindfv の優れた回答に加えて、絶対に任意の型を許可するパラメトリック ポリモーフィズムがあるため[a]、リスト内のBTree a任意の型を許可し、バイナリ ツリー内の任意の型を許可します。

これにより、「これらのタイプは互換性がありますか?」に対する 3 つの答えが得られます。

  1. いいえ; プログラマーはそうは言いませんでした。
  2. プログラマーがそう言ったので、特定の目的に相当します。
  3. 気にしないでください。データ自体のプロパティを使用しないため、このデータのコレクションに対して同じことを行うことができます。

4 はありません: コンパイラーは、他の関数のように 2 つの Int と String をたまたま使用したため、プログラマーを無効にします。

*Haskell が構造型付けに変わる可能性は低いと言いました。何らかの形式の拡張可能なレコードを導入するためのいくつかの議論がありますが、 と同じまたは同じように(Int,(Int,Int))カウントする計画はありません。(Int, Int, Int)Triple {one::Int, two::Int, three::Int}Triple2 {one2::Int, two2::Int, three2::Int}

于 2014-01-12T10:05:31.717 に答える
2

Haskell で構造的に型付けされたレコードの 2 つのライブラリ実装を認識しています。

HListは古く、優れた論文で説明されています

ビニールはより新しく、ファンシーな新しい GHC 機能を使用しています。それを使用している少なくとも 1 つのライブラリ、vinyl-gl があります。

ただし、質問の言語設計の部分にはお答えできません。

于 2014-01-13T15:01:59.490 に答える
1

最後の質問に答えると、Go と Scala には間違いなく構造型付けがあります。一部の人々 (私を含む) は、それを「静的に安全でない型付け」と呼んでいます。これは、プログラム内の同じ名前のすべてのメソッドが同じセマンティクスを持つことを暗黙的に宣言するためです。これは、ソース ファイルのコードをプログラムが見たことのないライブラリのコード。

IMO、同じ名前のメソッドが動作の名前付きセマンティック「モデル」に準拠していることを明示的に宣言することを要求することをお勧めします。

はい、コンパイラはメソッドが呼び出し可能であることを保証しますが、次のように言うよりも安全ではありません。

 f :: [a] -> Int

そして、コンパイラに任意の実装を選択させますlength

(同様のアイデアは、Scala の「implicits」または Haskell (GHC?) の「reflection」パッケージで安全にすることができます。)

于 2014-01-13T16:29:24.363 に答える