SML中不使用数据类型的多态加法函数

A polymorphic addition function in SML without using datatype

我在SML的学习上取得了一些进步,试图巩固我对一些最基本概念的理解。下面的练习证明还有很多东西要学。

我被要求实现一个名为 add 的函数,该函数接收两个数字并 return 计算它们的总和。问题是,add 应该接收整数和实数的不相交并集,并且 return 以下列方式接收不相交的并集:如果接收到的两个数字都是整数,它应该 return 总和作为整数.否则,如果两个参数之一为实数,则总和应 return 为实数。

最合理的解决方案是使用数据类型,但我被明确指示不要以任何方式、形状或形式使用它。换句话说,我应该实现某种机制来确定参数的类型,然后确定 return 类型。

所有的尝试都是徒劳的。 SML 要么推断我的参数是一种特定类型(事实并非如此),要么它要求 return 值是某种类型,这是可以理解的,但仍然令人沮丧。我不知道如何克服 SML 的输入限制。如果它有任何用处,我被暗示使用元组。

我觉得这个问题有点奇怪,因为在 SML 中,短语 "disjoint union" 通常 表示 datatype 声明定义的标记联合。关于使用元组的提示让我开始思考……选项。有一种自然的方式可以将 intreal 的不相交并集视为 int option * real option 子类型 ,例如5对应(SOME 5, NONE)5.0对应(NONE, SOME 5.0)。我知道在类型级别上没有办法强制执行隐含的限制,即唯一有效的模式涉及一个 SOME 和一个 NONE 但您可以定义您的函数,以便在您尝试使用它们时它们崩溃使用 (NONE,NONE)(SOME n, SOME r) 模式——要么不为这些模式提供定义,要么显式地引发错误。这将防止您的函数被用于除可被解释为位于联合类型中的值以外的任何值。

使用它,定义函数 add 相对容易,例如

add (SOME 1, NONE) (SOME 5, NONE)

计算为 (SOME 6, NONE)。由于这是一项任务,我不想多说什么。

我不完全确定这是你的导师所想的那种事情,尽管它看起来确实是一个合理的解释。

我真的建议您查看 John Coleman 提交的答案,因为这是最合理的处理方法。但是,我的导师有不同的想法。因此,为了子孙后代,这是我的原始且完全不切实际的实现,这是预期的:

fun add (a, b, _, _, 0) = (a+b, 0.0)
  | add (_, b, x, _, 1) = (0, real(b) + x)
  | add (_, _, x, y, _) = (0, x + y);

与 C 联合数据类型非常相似。包含 5 个元素的元组用于向函数发送参数:2 个整数条目、2 个实数条目和一个区分 3 种可能的添加方式的标签(int/int、int/real、real/real).同样,这只是出于教育目的而编写的,因此对于此功能的任何实际使用,请参阅 John Coleman 的回答。