Scala と Haskell の型システムの違いと類似点は何ですか?
-
07-07-2019 - |
質問
Haskell の専門家に Scala の型システムを説明するにはどうすればよいでしょうか?Scala の利点を示す例は何ですか?
Haskell の型システムを上級 Scala 実践者に説明するにはどうすればよいでしょうか?Haskell でできて Scala ではできないことは何ですか?
解決
Scala Haskell プログラマへ:
Scala は、ファーストクラスのモジュールを備えた厳密かつ不純な言語です。データ型は「クラス」または「トレイト」として宣言されますが、微妙な違いがあり、モジュールまたは「オブジェクト」はそれらの型の値です。Scala は、普遍的に数量化された型パラメーターを取る型コンストラクターをサポートしています。オブジェクト/クラス/トレイトには、値、変更可能な変数、関数 (「メソッド」と呼ばれる) で構成されるメンバーがあり、モジュールは変数として暗黙的に渡されます。 this
)。モジュールには、パラメーターも受け取ることができる型メンバーがある場合があります。型メンバーは存在的に定量化され、型パラメーターはより高次のものにすることができます。型はファーストクラスの値のメンバーになる可能性があるため、Scala は、と呼ばれる依存型付けのフレーバーを提供します。 パス依存型.
第一級関数もモジュールです。関数は、という名前のメソッドを持つモジュールです。 apply
. 。メソッドはファーストクラスではありませんが、メソッドをファーストクラス関数でラップするための構文が提供されています。残念ながら、モジュールはその型パラメータをすべて事前に必要とするため、部分的に適用された第一級関数を普遍的に定量化することはできません。より一般的には、Scala には 1 より高いランクの型に対する直接的なメカニズムがまったくありませんが、より高い種類の型でパラメータ化されたモジュールを利用して、ランク n の型をシミュレートできます。
Scala では、グローバル スコープを持つ型クラスの代わりに、任意の型の暗黙的な値を宣言できます。これには、暗黙的な変換、つまり型拡張を提供する関数型が含まれます。暗黙的な変換に加えて、モジュール間のサブタイプ/スーパータイプ関係を宣言できる「extends」メカニズムによって型拡張が提供されます。このメカニズムを使用すると、スーパータイプをデータ宣言の左側の型として、そのサブタイプを右側の値コンストラクターとして見なすことができる代数データ型をシミュレートすることができます。Scala には、最上級のパターンを備えた仮想化パターン マッチャーを使用した広範なパターン マッチング機能があります。
Scala はサブタイプをサポートしているため、型推論が大幅に制限されます。しかし、型推論は時間の経過とともに改善されました。より高次の種類の推論がサポートされています。ただし、Scala には意味のある種類システムがまったくないため、種類の推論も種類の統合もありません。型変数が導入された場合、それは一種です *
別段の注釈がない限り。次のような特定のタイプ Any
(すべての型のスーパータイプ) および Nothing
(あらゆるタイプのサブタイプ) は技術的には あらゆる種類の ただし、型引数には適用できません。
Haskell から Scala プログラマーへ:
Haskell は純粋な関数型言語です。これは、関数には副作用がまったく許可されていないことを意味します。たとえば、Haskell プログラムはそのままでは画面に出力されませんが、次の値を返す関数です。 IO[_]
IO サブシステムが実行する一連のアクションを記述するデータ型。
Scala はデフォルトで厳密であり、厳密ではない関数引数に「名前による」アノテーションを提供しますが、Haskell はデフォルトで「必要による」セマンティクスを使用して遅延し、厳密な引数にアノテーションを提供します。
Haskell の型推論は Scala よりも完全であり、完全な推論を備えています。これは、型アノテーションがほとんど必要ないことを意味します。
GHC コンパイラの最近の拡張機能により、ランク n 型、型ファミリー、種類ポリモーフィズムなど、Scala には同等の機能がない高度な型システム機能が可能になります。
Haskell では、モジュールは型と関数のコレクションですが、モジュールは第一級のエンティティではありません。暗黙的なものは型クラスによって提供されますが、これらは宣言されるとグローバルにスコープされ、Scala のように明示的に渡すことはできません。特定の型の型クラスの複数のインスタンスは、 newtype
これは曖昧さをなくすためですが、Scala では単にスコープを設定するか、インスタンスを明示的に渡すことによってこれが解決されます。
Haskell は「オブジェクト指向」ではないため、メソッド/関数の二分法はありません。すべての関数はファーストクラスであり、すべての関数はデフォルトでカリー化されます (Function1、Function2 などはありません)。
Haskell にはサブタイプのメカニズムはありませんが、型クラスはサブクラス関係を持つことができます。
他のヒント
私は誰もがHaskell(GHCの型システムで例示されている)とScalaを体系的に比較したとは思わない。主な違いは、型推論の程度と、より高いランクの型のサポートです。ただし、違いを完全に処理することは、公開可能な結果になります。