I have written a function that takes an array as input and returns an array of equal size as output. For example:
myFunc [| "apple"; "orange"; "banana" |]
> val it : (string * string) [] =
[|("red", "sphere"); ("orange", "sphere"); ("yellow", "oblong")|]
Now I want to assign the results via a let binding. For example:
let [|
( appleColor, appleShape );
( orangeColor, orangeShape );
( bananaColor, bananaShape )
|] =
myFunc [| "apple"; "orange"; "banana" |]
Which works great...
> val orangeShape : string = "sphere"
> val orangeColor : string = "orange"
> val bananaShape : string = "oblong"
> val bananaColor : string = "yellow"
> val appleShape : string = "sphere"
> val appleColor : string = "red"
...except it produces a warning:
warning FS0025: Incomplete pattern matches on this expression. For example, the value '[|_; _; _; _|]' may indicate a case not covered by the pattern(s).
The source and reason for the warning has already been covered, I'm just looking for a succinct work-around. This function call occurs near the top of my function, and I don't like the idea of putting the entire function body inside a match:
let otherFunc =
match myFunc [| "apple"; "orange"; "banana" |] with
| [|
( appleColor, appleShape );
( orangeColor, orangeShape );
( bananaColor, bananaShape )
|] ->
// ... the rest of my function logic
| _ -> failwith "Something impossible just happened!"
That just smells bad. I don't like the idea of ignoring the warning either - goes against my better judgment. Are there any other options open to me, or do I just need to find a different approach entirely?
One possibility if you expect this kind of calling pattern to be frequent is to make wrappers that act on the sizes of tuples you expect, e.g.
etc. But all it does is move the ugly code to a standard place, and writing out the wrappers will be inconvenient.
I don't think there's any better option with this API, because there's no way to tell the compiler that
myFunc
always returns the same number of elements it is passed.Another option might be to replace
myFunc
with anIDisposable
class:and then use it in a block like