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);会导致错误,因为zthrowsint而不是real.

但我的问题是线路x(3.0);,为什么它不会导致错误?

根据我的理解,xg(y),当我们执行时,x(3.0)我们实际上执行g(3.0),但g只抛出类型的异常int,但我们传递给g3.0,因此g会抛出一个real值,所以应该是违规,不是吗?

如果有人能解释为什么执行时没有发生错误,我将不胜感激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
-

所以,正如 U 所见,在这两种情况下我们都会得到错误。

因此,我回到第一方:为什么当两者都x(3.0)出现时z(3)(参见代码1,帖子开头发布的第一个代码),为什么SML只提到第二行(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),最终会出现以下错误,因为这两个函数的类型不正确

- 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。如果您删除对 的错误调用z,然后f在 SML 提示符中键入,那么您应该看到类型系统已经推断出类型

(real -> 'a)  -> 'a

为了它。这种类型非常好,它只是稍后在程序中的调用是错误类型的。f因为与要求g的参数类型不匹配real -> 'a

于 2013-02-23T07:36:31.773 回答
1

最初的误解源于不了解何时检测到类型错误。标准 ML 是一种强静态类型的语言。这意味着类型检查都是在编译时完成的,当函数第一次被解释器读取时,而不是在运行时。这意味着类型错误是在代码执行之前生成的,Jesper 正确地指出了这一点。这两种类型错误正是 Jesper 在 f(g) 表达式和 z(3) 表达式中指出的地方。编译表达式时,表达式 x(3.0) 没有任何问题。如果静态类型检查根本没有阻止程序运行,那只会有问题。像 Python 这样的动态类型语言将允许该程序运行并在计算 x(3.0) 表达式时引发 Ron 建议的异常。

于 2014-04-07T19:15:43.103 回答