9

文字列で定義することでし(+)たが、のインスタンスを指定することではないとしますNum String

Haskellが関数を非表示にするNumのはなぜですか?(+)結局のところ、私が提供した機能は次のとおりです。

(+) :: String -> String -> String

コンパイラによってプレリュードと区別することができます(+)。両方の関数が同じ名前空間に存在できないのに、重複しない型シグネチャが異なるのはなぜですか?

コード内に関数の呼び出しがない限り、Haskellはあいまいさが存在することに注意します。引数を使用して関数を呼び出すと、適切な実装を選択できるようにタイプが決定されます。

もちろん、インスタンスNum Stringが存在すると、実際には競合が発生します。その時点で、Haskellは、関数が実際に呼び出された場合、どの実装を選択するかをパラメータータイプに基づいて決定できなかったためです。
その場合、エラーが発生するはずです。

これにより、落とし穴やあいまいさを伴わずに関数のオーバーロードが可能になりませんか?

注:動的バインディングについては話していません。

4

2 に答える 2

19

Haskell は単純に関数のオーバーロードをサポートしていません (型クラスによるものを除く)。その理由の 1 つは、関数のオーバーロードが型推論でうまく機能しないことです。のようなコードがある場合f x y = x + y、Haskellは が Nums か文字列か、つまり の型が かかどうかxをどのように知るのでしょうか?yff :: Num a => a -> a -> af :: String -> String -> String

PS:これはあなたの質問にはあまり関係ありませんが、オープンワールドを想定している場合、つまり、あるモジュールのどこかに のインスタンスがある可能性がある場合、型は厳密には重複していません。Num Stringインポートすると、コードが壊れます. したがって、Haskell は、特定の型が特定の型クラスのインスタンスを持たないという事実に基づいて決定を下すことはありません。もちろん、型クラスが含まれていなくても、関数定義は同じ名前の他の関数定義を隠しているので、私が言ったように、あなたの質問にはあまり関係ありません。


呼び出しサイトで推論されるのではなく、定義サイトで関数の型を知る必要がある理由について: まず第一に、関数の呼び出しサイトは、関数定義とは異なるモジュール (または複数のモジュール) にある可能性があります。したがって、関数の型を推測するために呼び出しサイトを調べる必要がある場合は、モジュールの境界を越えて型チェックを実行する必要があります。つまり、モジュールを型チェックするとき、このモジュールをインポートするモジュールもすべて調べなければならないため、最悪の場合、単一のモジュールを変更するたびにすべてのモジュールを再コンパイルする必要があります。これにより、コンパイル プロセスが非常に複雑になり、速度が低下します。さらに重要なことは、ライブラリのコンパイルが不可能になることです。

于 2013-02-06T10:09:24.997 に答える
7

関数が呼び出されない限り

ある時点で、関数を使用するとき

ダメダメダメ。Haskellでは、「前」や「あなたがする分...」については考えませんが、常に何かを定義します。これは、変数の実行時の動作で最も明白ですが、関数のシグネチャとクラスインスタンスにも変換されます。このように、コンパイル順序について面倒な考えをすべて行う必要はなく、プログラムの1つの小さな変更のために、C++テンプレート/オーバーロードがひどく壊れることが多いなどの多くの方法から安全です。

また、Hindley-Milnerがどのように機能するかをよく理解していないと思います。

関数を呼び出す前に、引数のタイプがわかっているときに、それを知る必要はありません。

さて、あなたは通常、引数のタイプを知りません!明示的に指定されることもありますが、通常は他の引数または戻り型から推測されます。たとえば、

map (+3) [5,6,7]

コンパイラは、数値リテラルのタイプを認識せず、それらが数値であることを認識しているだけです。このように、あなたはあなたが好きなように結果を評価することができます、そしてそれはあなたが他の言語でしか夢見ることができなかったもの、例えばシンボリックタイプを可能にします

> map (+3) [5,6,7] :: SymbolicNum
[SymbolicPlus 5 3, SymbolicPlus 6 3, SymbolicPlus 7 3]
于 2013-02-06T11:20:27.287 に答える