1

说在标准 ML 中定义几种数据类型:

datatype color = orange | navy | teal | silver | hsl of real * real * real;

datatype direction = east | north | west | south;

然后我定义一个使用上述数据类型的值:

type Cursor = int * int * color * direction;

val cursor : Cursor = (0, 0, orange, east);

它是一个具有位置、绘图颜色和方向的“光标”。我想要的是它的属性最初是 undefined。我可以为每个数据类型添加一个构造函数colordirection我将如何使用int位置值来做到这一点?),如下所示:

datatype color = orange | teal | silver | hsl of real * real * real | undefined;

datatype direction = east | north | west | south | undefined;

val cursor : Cursor = (0, 0, undefined, undefined);

我想这样做,undefined不必为每个数据类型显式定义一个额外的构造函数。你能想出一个好的、干净的解决方案吗?某种形式的泛型,无论类型如何,我都可以简单地使用“未定义值”的形式。Nullable粗略地说,类似于 Javas 。

我的动机是我的光标的属性最初是未定义的。

4

2 回答 2

3

没有语法糖可以引用具有相同名称的不同构造函数。(换句话说:标准 ML 不允许自定义重载。)相反,首先声明的构造函数被另一种类型的类似拼写构造函数覆盖。

Haskell 有一个名为的值undefined,在评估时会引发异常。因此,此值的类型不受任何特定类型的限制,并且是多态的,这意味着 undefined 可以在任何地方使用。

标准 ML 不能将此值定义为引发异常的别名,因为它是经过严格评估的。这意味着在val undefined = raise Undefined声明的那一刻,抛出异常。但是可以raise Undefined在尚未编写的程序的某些部分中使用,只要它不立即评估即可。

'a option代数类型的一个非常重要的优势是,除非您明确地形成支持它的类型(例如使用),否则您不会意外地拥有类似 null 的值。

于 2012-10-30T18:08:56.253 回答
3

为此,人们通常使用一种option类型。

您生成的机器人类型将是:

type Robot = (int * int * color * direction) option;

或组件明智。这也与自己简单地使用两个构造函数(一个表示未定义值,一个表示初始化值)创建数据类型相同,但这option是一种标准方法,它也鼓励单子编程风格。

这可以确保您的类型安全,因为每当您破坏类型的值时,您都需要匹配两个构造函数。

于 2012-10-29T17:02:11.297 回答