5

我开始喜欢 OCaml 中的这种语法

match myCompare x y with
|Greater->
|Less->
|Equal->

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

如果不执行上述步骤,无论如何都会这样做吗?

pervasives 模块似乎有“比较”,如果相等则返回 0,大于时返回 pos int,小于时返回 neg int。有可能匹配那些吗?概念上像这样(不编译):

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

我知道我可以只使用 if 语句,但模式匹配对我来说更优雅。有没有一种简单的(如果不是标准的)方法可以做到这一点?

4

2 回答 2

7

有没有一种简单的……方法可以做到这一点?

不!

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

这实际上说,是的!

你可以写:

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也可以用另一种语言表示的文件描述符。类型定义没有任何运行时成本。在这个例子中没有理由不使用一个。

于 2013-08-24T07:14:45.590 回答
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 -> ...
于 2013-08-24T07:44:31.207 回答