1

次のコードを考えると:

exception E of int;
fun g(y) = raise E(y);
fun f(x) = 
    let 
      exception E of real;
      fun z(y)= raise E(y);
    in 
      x(3.0);
      z(3)
    end;
f(g);

SML でコードを実行すると、次のようになります。

stdIn:216.8-216.12 Error: operator and operand don't agree [literal]
  operator domain: real
  operand:         int
  in expression:
    z 3

z(3);それは結構です - 行がエラーを引き起こすzことを理解していintますreal.

しかし、私の問題は行x(3.0);にあります。なぜエラーが発生しないのですか?

私の理解でxg(y)、 を実行すると、x(3.0)実際には を実行しますが、タイプ の例外のみをスローしますが、値に渡したので、値をスローするので、違反になるはずですよね?g(3.0)gintg3.0greal

実行時にエラーが発生しない理由を誰かが説明できれば幸いx(3.0)です。

ありがとう

編集:

を削除するz(3);と、意味:

- fun f(x) =
=     let
=       exception E of real;
=       fun z(y)= raise E(y);
=     in
=       x(3.0)
=
=     end;
val f = fn : (real -> 'a) -> 'a
- f(g);

出力は次のとおりです。

stdIn:11.1-11.5 Error: operator and operand don't agree [tycon mismatch]
  operator domain: real -> 'Z
  operand:         int -> 'Y
  in expression:
    f g
-

したがって、ご覧のとおり、どちらの場合もエラーが発生します。

したがって、私は振り出しに戻ります: なぜ と の両方が次々にx(3.0)表示されるのにz(3)(コード 1、投稿の冒頭に投稿された最初のコードを参照)、なぜ SML は 2 行目のエラーのみを参照するのですか ( z(3);)最初の行が () を引き起こしたエラーではありませんx(3.0);

再び10倍

4

3 に答える 3

1

問題は、xがfに渡される関数であるという事実にあります。したがって、関数fを入力すると、引数xは何にも拘束されないため、常に正しい型になります。f(g)直後に関数適用があるという事実は、関数のタイプを推測するときに何の役割も果たしませんf

ローカル関数zをの定義の外に移動するfと、非常に単純なものになり、次のように入力されます。

exception R of real;
fun z(y)= raise R (y);

exception I of int;
fun g(y) = raise I (y);

fun f(i, r) = (i(3.0); r(3))

ただし、次に呼び出すf(g,z)と、2つの関数が正しいタイプではないため、次のエラーが発生します。

- f(g, z);
stdIn:78.1-78.8 Error: operator and operand don't agree [tycon mismatch]
  operator domain: (real -> 'Z) * (int -> 'Y)
  operand:         (int -> 'X) * (real -> 'W)
  in expression:
    f (g,z)
于 2013-02-22T15:17:03.433 に答える
1

Jesperの優れた答えを補完するために:言い換えれば、xinsideへの呼び出しに問題はありませんf。への誤った呼び出しを削除してからSMLプロンプトに入力するzf、型システムが型を推測したことがわかります。

(real -> 'a)  -> 'a

それのための。その型は完全に問題ありません。型が正しくないのは、プログラムの後半での呼び出しにすぎません。必要に応じてパラメータタイプと一致しないfためです。greal -> 'a

于 2013-02-23T07:36:31.773 に答える
1

最初の誤解は、型エラーがいつ検出されたかを理解していなかったことが原因でした。標準 ML は、強く静的に型付けされた言語です。これは、実行時ではなく、関数がインタープリターによって最初に読み取られるコンパイル時にすべての型チェックが行われることを意味します。これは、コードが実行される前に型エラーが生成されることを意味し、Jesper は正しく指摘しました。2 つの型エラーは、f(g) 式と z(3) 式で Jesper が示した場所とまったく同じです。式をコンパイルすると、式 x(3.0) に問題はありません。静的型チェックによってプログラムの実行がまったく妨げられない場合にのみ、問題が発生します。Python のような動的に型付けされた言語では、このプログラムを実行して、Ron が x(3.0) 式がいつ評価されたかを示唆する例外を発生させることができます。

于 2014-04-07T19:15:43.103 に答える