假设您想使用< 运算符,不。运算符 < 并不是真正的多态,而是以标准 ML 中不可扩展的方式简单地重载。这与支持新类型重载的= 不同。 = 的类型是 ''a * ''a -> bool,可以理解为:鉴于 'a 是一种可以比较是否相等的类型,= 采用这种类型的两个值并返回一个 bool 类型的值. 当然,并不是所有的多态值都可以比较是否相等。函数就是一个例子。
按特定属性(例如比较相等或排序)对某些多态值进行分组的概念在 Haskell 中称为 类型类,标准 ML 的相等类型是标准中唯一支持的类型类机器学习。
当您查看< 的类型时,它是int * int -> bool 或string * string -> bool,或者第三个,具体取决于上下文。如果支持标准 ML(例如),那就太好了。 '''a 表示可以排序的多态值。但是这个符号在前两个或三个类型类之后变得乏味并且一个徘徊和does what Haskell does。
最简单的替代方法是为某些具体类型t 传递一个排序函数t * t -> order,其中order 是具有值LESS、EQUAL 和GREATER 的内置类型(看起来比bool 稍微不那么花哨,但从长远来看会更好)。当将此类比较运算符传递给需要比较任意类型的所有函数时,最终会变得很烦人,因为您要为很多类型和很多函数这样做,您可以发明一个签名,
signature ORDERABLE =
sig
type t
val compare : t * t -> order
end
以及每当您需要对可以订购的东西做一些通用的事情时,例如把它们放到二叉树中,就可以创建函子了,
functor BinTree (SomeOrd : ORDERABLE) =
struct
(* Let's export SomeOrd into this functor for convenience *)
type t = SomeOrd.t
val compare = SomeOrd.compare
datatype tree = Leaf of t | Node of tree * t * tree
val singleton = Leaf
fun insert (x, Leaf) = Leaf x
| insert (x, Node (l, y, r)) =
case compare (x, y) of
GREATER => Node (l, y, insert (x, r))
| _ => Node (insert (x, l), y, r)
fun member (x, Leaf y) = compare (x, y) = EQUAL
| member (x, Node (l, y, r)) =
case compare (x, y) of
EQUAL => true
| LESS => member (x, l)
| GREATER => member (x, r)
end
可以这样使用,
structure IntBinTree = BinTree(struct
type t = int
val compare = Int.compare
end)
val myTree = IntBinTree.insert(5, IntBinTree.insert(3, IntBinTree.singleton 4))
这里的重点是,在函子BinTree 中,所有函数都可以理所当然地接受顺序比较运算符compare,因此它们不必将它们作为参数传递。缺少多态顺序比较运算符和实现自定义重载的方法,我认为这两个选项是标准 ML 必须提供的最佳选择。