我定义了一些复杂的数据类型,例如:
type drawer =
{ ...
box: boxes list }
type table =
{ ...
drawers: drawer list }
type room =
{ ...
tables: table list }
我想定义一些类似用途的函数,但是使用不同类型的参数,例如:
val compare_size_rooms: room -> room -> bool (* true: bigger, false: smaller *)
val compare_size_tables: table -> table -> bool
val compare_size_boxes: box -> box -> bool
有一件事是,有时候,由于结构不同,2个房间/桌子/盒子可能无法比较,因此我希望比较可以给我一些额外的信息,除了真或假。
我的问题是,这是否是定义类型info
的常用方法:
type info =
| Incomparable_Tables_One_foldable_Another_non_foldable
| Incomparable_Tables_One_rectangle_Another_triangle
| Incomparable_Boxes_One_in_paper_Another_in_metal
| ...
我的功能如下:
val compare_size_rooms: room -> room -> bool * info (* true: bigger, false: smaller *)
val compare_size_tables: table -> table -> bool * info
val compare_size_boxes: box -> box -> bool * info
因此,在这些函数中,我分析2个值,如果它们具有可比性,则bool
返回值更大或更小,否则,info
将返回有用的分析信息。
这种结构似乎不太常见,有人能告诉我它是否正常,或者如果有更好的方法可以实现同样的事情?
非常感谢
答案 0 :(得分:1)
如果您要比较的两个对象不具有可比性,则不建议返回一个布尔值,就好像它们是可比较的一样。相反,您可以引发异常:
exception Incomparable_Tables_One_foldable_Another_non_foldable
let compare_size_tables a b =
if comparable a b then
a.size < b.size (* Or whatever you do *)
else
raise Incomparable_Tables_One_foldable_Another_non_foldable
(* val compare_size_tables : table -> table -> bool *)
替代方法是使用变量返回类型,它可以是布尔值(当对象可比较时)或信息类型(当它们不是时)。例如,使用电池库:
open BatPervasives
type info =
| Incomparable_Tables_One_foldable_Another_non_foldable
| ...
let compare_size_tables a b =
if comparable a b then
Ok (a.size < b.size)
else
Bad (Incomparable_Tables_One_foldable_Another_non_foldable)
(* val compare_size_tables : table -> table -> (bool, info) BatStd.result *)
在后一种情况下,您必须match
结果是Bad info
还是Ok boolean
。