无需先转为整数/浮点数即可比较自定义类型参数的实现方法
答案
完全不需要手动把colour类型的值转成整数、浮点数这类原生可比较值,两种方案都可以直接实现你要的大小比较,匹配「每套一层Shade取值就比Base大1个单位」的规则:
- 直接用OCaml自带的多态比较运算符就行。OCaml里变体类型的默认比较逻辑本来就按构造器的声明顺序定大小:先写的构造器对应值更小,后写的更大;如果两个值是同一个带参数的构造器,就递归比构造器里带的参数。
你现在的定义里Base写在最前面,构造器序号是0,Shade写在后面序号是1,天然满足所有Shade _包装出来的值都比Base大;两个Shade值比较的时候会递归比里面包的colour值,刚好符合多层Shade逐层增大的规则,直接写比较表达式就能跑:
唯一要注意的是,后续如果调整了两个构造器的声明顺序,默认比较的结果就会反过来,如果类型定义不会随便改这个方案是最省事的。(* 以下比较结果均为true,符合预期规则 *) Base < Shade Base Shade Base < Shade (Shade Base) Shade (Shade Base) > Base - 如果怕后续改类型定义把比较逻辑搞乱,可以自己写递归比较函数,全程不用做类型转换,直接模式匹配变体结构就行:
比较的时候调用这个函数就行:返回-1表示第一个参数更小,0表示相等,1表示第一个参数更大,逻辑完全可控,也不需要做任何到原生数值类型的转换。let rec colour_compare a b = match a, b with | Base, Base -> 0 | Base, Shade _ -> -1 | Shade _, Base -> 1 | Shade a', Shade b' -> colour_compare a' b'
内容的提问来源于stack exchange,提问作者heris
相关产品推荐
相关产品推荐

