一个类型“info”,可以从函数中获得更多结果

时间:2011-07-19 21:27:07

标签: function types ocaml

我定义了一些复杂的数据类型,例如:

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将返回有用的分析信息。

这种结构似乎不太常见,有人能告诉我它是否正常,或者如果有更好的方法可以实现同样的事情?

非常感谢

1 个答案:

答案 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