1

我明天要参加 SML/NJ 的考试,我在过去的几个不同的决赛中看到了这个问题,但我不知道该怎么想。

假设在(虚构的)语言 PML 中,我们将 int 作为 float 的子类型。对或错?

  1. 总是可以提供 int -> int 类型的函数来代替 int -> float 类型的函数。(真的?)
  2. 总是可以提供 int -> bool 类型的函数来代替 float -> bool 类型的函数。(真的?)
  3. 总是可以提供 int -> (int ref) 类型的函数来代替 int -> (float ref) 类型的函数。(错误的?)
  4. 始终可以提供 (int x float ) -> int 类型的函数来代替 (float x int ) -> float 类型的函数。(错误的?)
4

1 回答 1

2

这是子类型的定义:http ://en.wikipedia.org/wiki/Subtyping

如果float是超类型,并且int是子类型,那么您可以将 a 传递int给任何需要 a 的函数float。在面向对象的范例中,您会说int扩展或下降float意味着int可以在任何地方使用float罐头,但反之亦然。

我的想法是对程序员的期望。如果您有一个过去采用 int 的函数,您希望仍然能够给它一个 int。所以你不能替换任何不是 int 子类型的东西。对于输出,如果您希望得到一个 int,则交换函数不能返回除 int 或子类型以外的任何内容。否则,当您将该返回值传递给下一个函数时,它可能会中断。

现在真/假:

  1. 是的int -> float,因为如果您想象将函数与int -> int高阶函数中的函数交换或将返回值传递给另一个函数:

    round (int_to_float x) (* or *) round (int_to_int x)
    

    round 将能够处理浮点数和整数。

  2. false因为新函数可能会利用int传入的浮点数无法容纳的特定属性。例子:

    fun negative x = x < 0 
    (* subbed for *) 
    fun even x = x mod 2 == 0
    

    显然,即使是负数也会导致错误

  3. false因为您必须同时考虑从参考中读取和写入参考。从参考资料中阅读时:

    !x:float    (* int ref or float ref work *)
    x := n:int  (* only int ref works *)
    

    这就是问题所在。读时宽以一种方式,写作时宽以另一种方式。唯一的重叠是一种类型,所以你不能替换 refs。

  4. 错误的

于 2013-04-26T06:42:48.700 回答