2016-10-26 46 views
0

我有一個返回數組的最小值的函數。模式匹配數組

功能有類型:

min : int array -> int 

它的實現:

let rec min a = match a with 
    | [] -> 1000000000 
    | x :: [] -> x 
    | x :: xs -> let ms = min xs in if x < ms then x else ms;; 

不過,我得到這個錯誤:

Found min with unexpected type: 
Wrong type int list -> int. 

所以,我怎麼能匹配模式的數組?

+1

「1000000000」會給某些輸入提供不正確的結果,您應該找到一種不涉及幻數的方法。 – coredump

+0

您正在以錯誤的方式訪問IMO。您可以使用數組語法對陣列進行模式匹配。但是這裏沒有head :: tail pattern。數組是通過索引直接訪問的。如果您願意,可以將數組轉換爲列表。 –

回答

5

您在您的模式中使用列表符號,這是導致問題的原因。數組常量是這樣的:[| 3; 4; 5 |]

排列花紋看起來是一樣的,因爲你會期望:

let f = function 
| [| |] -> "empty" 
| [| _ |] -> "one" 
| [| _; _ |] -> "two" 
| _ -> "many" 

每個排列形態的特定大小的數組匹配。沒有匹配至少有一定大小的數組。這與列表相反,這種靈活性可用。

與其使用模式匹配,更有用的處理數組的方法可能是使用Array.fold_leftArray.fold_right

也許你已經習慣了那裏數組和列表都或多或少同樣的事情的語言。在OCaml中,你必須選擇你想要使用哪一個。

4

與列表不同,數組沒有歸納定義。例如,一個列表是一個空列表或一對元素和另一個列表。歸納數據定義很好,因爲它們允許歸納地推理數據,即遞歸地推理數據。該數組是一個非常不同的數據結構,它被定義爲相同類型的固定數量的元素。所以,你的算法不適用於數組。問題不僅在於語法。您無法通過陣列上的歸納來表達最小值。你需要找到一些其他的方式來表達最小,例如,最小尺寸N的數組A的是這樣的元素,m,對所有i, 0 <= i < N我們m <= A(i)。如果你遵循這個定義,那麼你可以直接實現它。從第一個元素開始,作爲最小值的近似值,然後繼續下一個元素,如果它小於當前最小值,則更新近似值。一旦您檢查了所有元素,您的最小值將滿足所需的屬性。

什麼關於空案例,那麼你可以決定最小值未定義爲空數組。 Tha會使你的函數不是全部的,你可以通過返回類型int option或者隱式地通過引發一個異常來顯式表示,並且在註釋中聲明該函數只是爲非空數組定義的。或者,您可以將max_int作爲空數組的最小元素返回,因爲空集的最大下界是該Universe的最大值(在我們的示例中爲max_int)。

+0

關於'max_int',這是相關的:http://math.stackexchange.com/q/3768/131235 – coredump