2013-08-24 112 views
4

我来爱这个语法OCaml中匹配比较OCaml的

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

但是,它需要两件事情,一个自定义类型,并返回我的自定义类型myCompare功能。

如果不按照上面的步骤进行操作,会不会有呢?

普及模块似乎有'比较',如果相等则返回0,如果大于则返回pos,否则返回小于等于int。有可能匹配那些吗?概念上是这样的(不编译):

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

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

回答

6

有没有一种简单的方法呢?

不!

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

+1,但我相信问题的动机是OCaml本身 - 不幸的是 - 使用有符号整数进行比较操作。 –

+3

@AndreasRossberg我意识到写完我的回答/咆哮后。那么,Caml应该真的有一个'Greater |较少| “平等”类型并将其用于所有“比较”功能。而且它还可以省去我们写'let compare_int x y = x - y'的人(不是因为溢出而产生的传递关系)。 –

+0

真的很遗憾,比较回报如下:(尽管+1,非常有用写出来 – Secret

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 -> ...