Sml 如何实施某种形式的;“可为空”;标准ML中的类型?

Sml 如何实施某种形式的;“可为空”;标准ML中的类型?,sml,smlnj,Sml,Smlnj,假设在标准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, e

假设在标准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);
它是一个“光标”,具有位置、绘图颜色和方向我希望它的属性最初是未定义的。我可以为每个
color
direction
数据类型添加一个构造函数(如何使用
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);
我想这样做,而不必为每个数据类型显式定义一个额外的
未定义的
构造函数。你能想出一个好的、干净的解决办法吗?某种形式的泛型,我可以简单地使用“未定义值”的形式,而不考虑类型。粗略地说,它类似于Javas
Nullable


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

为此,人们通常使用类型

生成的机器人类型将是:

type Robot = (int * int * color * direction) option;
或者组件方面。这也与您自己使用两个构造函数(一个表示未定义的值,另一个表示初始化的值)创建一个数据类型相同,但是
选项
是实现这一点的标准方法,它也鼓励采用一元编程风格


这会使您获得类型安全性,因为每当您销毁类型的值时,都需要匹配两个构造函数。

为此,人们通常使用类型

生成的机器人类型将是:

type Robot = (int * int * color * direction) option;
或者组件方面。这也与您自己使用两个构造函数(一个表示未定义的值,另一个表示初始化的值)创建一个数据类型相同,但是
选项
是实现这一点的标准方法,它也鼓励采用一元编程风格


这使您获得了类型安全性,因为每当您销毁类型的值时,都需要匹配两个构造函数。

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

Haskell有一个名为
undefined
的值,该值在计算时抛出异常。因此,该值的类型不受任何特定类型的约束,并且是多态的,这意味着可以在任何地方使用undefined

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


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

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

Haskell有一个名为
undefined
的值,该值在计算时抛出异常。因此,该值的类型不受任何特定类型的约束,并且是多态的,这意味着可以在任何地方使用undefined

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


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

当然,我怎么会错过这一点(已经阅读了
option
)!谢谢,我将尝试合并此选项,然后返回并标记您的答案为正确答案:-)当然,我怎么会错过此选项(已经阅读了
选项
)!谢谢,我将尝试合并此内容,然后返回并标记您的答案为正确答案:-)+1用于与
未定义的
进行比较,并注意到Haskell中的缩减顺序(与严格的ML相比)会导致差异。+1用于与
未定义的
进行比较,并注意到Haskell中的缩减顺序(与严格的ML相比)导致了不同。