質問

のコメント Steve Yegge's ポストサーバサイドJavascript を議論し始めたのメリットタイプシステム言語で、この コメント 説明:

...事例から H-M スタイルシステムが取得でき合う

expected signature Int*Int->Int but got Int*Int->Int

できれば関数の定義の中には?) との呼び出しを作ること。のように見えるのですがなかなかハードデバッグの大規模なっぽです。

また、がっているが、同様のエラー ミランダ?してくれてありがとうございます使用しないでに15年間で私の記憶が曖昧)

役に立ちましたか?

解決

私は、Yegge(およびOla Bini)の静的な型付けに関する意見を一粒の塩を使って受け取ります。静的型付けが提供するものに感謝すれば、選択したプログラミング言語の型システムがどのように機能するかを学習できます。

IIRC、MLはタプルに「*」構文を使用します。 < type> *< type> 2つの要素を持つタプル型です。したがって、(1、2)はint * int型になります。

HaskellとMLの両方の使用->機能のため。 MLでは、int * int-> intは、intとintのタプルを取り、それをintにマップする関数のタイプです。

別の言語からMLにアクセスするときにオラが引用したような漠然と見えるエラーが表示される理由の1つは、CやPascalの場合のように括弧とコンマを使用して引数を渡そうとした場合です2つのパラメーターを取る関数。

問題は、関数型言語は一般に複数のパラメーターの関数を関数を返す関数としてモデル化することです。すべての関数は単一の引数のみを取ります。関数が2つの引数を取る必要がある場合、代わりに引数を取り、単一の引数の関数を返します。これにより、最終結果が返されます。このすべてを読みやすくするために、関数の適用は単純に組み合わせて実行されます(つまり、式を並べて配置します)。

したがって、MLの単純な関数(注:私はMLとしてF#を使用しています)は次のようになります。

let f x y = x + y;;

タイプは次のとおりです:

val f : int -> int -> int

(整数を取り、それ自体が整数を取り、整数を返す関数を返す関数。)

ただし、タプルで単純に呼び出す場合:

f(1, 2)

... intが必要なものにint * intを渡したため、エラーが発生します。

これが「問題」だと思うオラはアスペションを投げかけようとしました。しかし、彼が考えているほど問題が悪いとは思わない。確かに、C ++テンプレートでははるかに悪いです。

他のヒント

まれてくる可能性があることでこれを参考には書きのコンパイラのある失敗を挿入する括弧をdisambiguateエラーメッセージが返されます。具体的には、機能予定の要素からなるタプル int 戻る int, すが、渡された要素からなるタプルの int 機能から intint.具体的には(ML):

fun f g = g (1, 2);

f (42, fn x => x * 2)

このことを演出しタイプエラー、例えば次のようなもの:

予想される型 int * int -> int, たタイプ int * (int -> int)

場合は、括弧を省略しているこのエラーがある督促になりました。

このことは特筆に値することでこの問題は明らかであろう特定のHindley-Milner.と思いつかないのかタイプ 誤差 ある特定のH-M少なくともしないような例を与えた。思オで吹き付けます。

多くの関数型言語では、変数を再バインドするのと同じ方法で型名を再バインドできるため、特に型に多少一般的な名前を使用している場合(たとえば、 t )別のモジュールで。 OCamlの簡単な例を次に示します。

# let f x = x + 1;;
val f : int -> int = <fun>
# type int = Foo of string;;
type int = Foo of string
# f (Foo "hello");;
This expression has type int but is here used with type int

ここで行ったことは、型識別子 int を、組み込みの int 型と互換性のない新しい型に再バインドすることです。もう少し努力すれば、上記とほぼ同じエラーを取得できます。

# let f g x y = g(x,y) + x + y;;
val f : (int * int -> int) -> int -> int -> int = <fun>
# type int = Foo of int;;
type int = Foo of int
# let h (Foo a, Foo b) = (Foo a);;
val h : int * int -> int = <fun>
# f h;;
This expression has type int * int -> int but is here used with type
  int * int -> int
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top