I am trying to build a general numeric function to take an array of floats, and then return an array of tuples that breaks up the array into N ranges of equal distance, where each tuple represents the lower and upper bound of each range. The first element of the 1st tuple in the resulting array should be the minimum of the input array, and the second element of the last tuple in the resulting array should be the maximum of the input array.
My problem is that I’m trying to solve this using pattern matching, and my code compiles, but it doesn’t create anything (?) I do get a warning saying the the 3rd pattern will never match. I’m puzzled, because I thought I had all the cases covered – 1st, last, and then everything in between. Thanks in advance for any good ideas on how to fix this code.
let rand1000 = [| for i in 1..1000 do yield rnd.NextDouble() |]
let intervals (arr: float array) (n : int) =
let L = Array.min(arr);
let U = Array.max(arr);
let increment = U - L / (float n);
let maxGroup = n-1;
[| for i in 0..maxGroup do
let range = match i with
| 0 -> L, L + increment
| maxGroup -> L + (float n) * increment, U
| _ -> L + (float n) * increment, L + (float (n + 1)) * increment
yield range
|]
let inters = intervals rand1000;
The 3rd pattern will never match because maxGroup matches any value. Only literal values can be used in match blocks, not very intuitive. You are creating a locally scoped variable name bound to the matched pattern. You want to use a when clause, like this:
This simply matches any value when i equals maxGroup.
Chris Smith has some examples that better demonstrate this feature: http://blogs.msdn.com/chrsmith/archive/2008/10/03/f-zen-the-literal-attribute.aspx