2013-08-24 113 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 -> ...