我在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语句,但模式匹配对我来说更优雅。这样做是否容易(如果不是标准的话)?
答案 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 -> ...