匹配比较OCaml

时间:2013-08-24 07:07:43

标签: functional-programming ocaml

我在OCaml

中喜欢这种语法
match myCompare x y with
|Greater->
|Less->
|Equal->

但是,它需要两件事,一个自定义类型和一个返回我的自定义类型的myCompare函数。

如果不执行上述步骤,是否仍然可以执行此操作?

pervasives模块似乎有'compare',如果相等则返回0,当更大时返回pos int,当less时返回neg int。有可能匹配那些吗?从概念上讲是这样的(不编译):

match myCompare x y with
| (>0) ->
| (0)  ->
| (<0) ->

我知道我可以使用if语句,但模式匹配对我来说更优雅。这样做是否容易(如果不是标准的话)?

2 个答案:

答案 0 :(得分:7)

  

有这么简单的方法吗?

没有!

match优于switch在另一种语言中的优势在于OCaml的match告诉您是否考虑过涵盖所有案例(并允许深入匹配并更有效地编译,但这也可以被视为类型的优势)。如果你做了一些愚蠢的事情,如果你开始使用任意条件而不是模式,你将失去被警告的优势。您最终会得到一个与switch具有相同缺点的构造。

这说,实际上,是的!

你可以写:

match myCompare x y with
| z when (z > 0) -> 0
| 0 -> 0
| z when (z < 0) -> 0

但是使用when会让你失去被警告的好处,如果你做了一些愚蠢的事情。

自定义类型type comparison = Greater | Less | Equal和三个唯一构造函数上的模式匹配是正确的方法。它记录了myCompare所做的事情,而不是让它返回int,它也可以用另一种语言表示文件描述符。类型定义没有任何运行时成本。在这个例子中没有理由不使用它。

答案 1 :(得分:4)

您可以使用已提供变量返回比较功能的库。例如,电池的BatOrd模块就属于这种情况。

否则,最好的办法是定义类型并创建从整数到比较的转换函数。

type comparison = Lt | Eq | Gt
let comp n =
  if n < 0 then Lt
  else if n > 0 then Gt
  else Eq

(* ... *)

match comp (Pervasives.compare foo bar) with
  | Lt -> ...
  | Gt -> ...
  | Eq -> ...