2016-10-26 47 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