解决脆弱模式匹配的建议 [英] Suggestion for solving fragile pattern matching
问题描述
我经常需要匹配应该有相同构造函数的值的元组。总结 _,_
总是结束。这当然是脆弱的,任何额外的构造函数添加到类型将编译得很好。我目前的想法是有连接第一个但不是第二个参数的匹配。但是,有没有其他选择?
I often need to match a tuple of values that should have the same constructor. The catchall _,_
always winds-up at the end. This of course is fragile, any additional constructor added to the type will compile perfectly fine. My current thoughts are to have matches that connect the first but not second argument. But, is there any other options?
例如,
For example,
type data = | States of int array
| Chars of (char list) array
let median a b = match a,b with
| States xs, States ys ->
assert( (Array.length xs) = (Array.length ys) );
States (Array.init (Array.length xs) (fun i -> xs.(i) lor ys.(i)))
| Chars xs, Chars ys ->
assert( (Array.length xs) = (Array.length ys) );
let union c1 c2 = (List.filter (fun x -> not (List.mem x c2)) c1) @ c2 in
Chars (Array.init (Array.length xs) (fun i -> union xs.(i) ys.(i)))
(* inconsistent pairs of matching *)
| Chars _, _
| States _, _ -> assert false
推荐答案
您可以使用下面略短的模式:
You can use the slightly shorter pattern below:
| (Chars _| States _), _ -> assert false
实际上,您可以让编译器为您生成它,因为它仍然有点乏味。
输入以下内容并编译:
In fact, you can let the compiler generate it for you, because it's still a little tedious. Type the following and compile:
let median a b = match a,b with
| States xs, States ys ->
assert( (Array.length xs) = (Array.length ys) );
States (Array.init (Array.length xs) (fun i -> xs.(i) lor ys.(i)))
| Chars xs, Chars ys ->
assert( (Array.length xs) = (Array.length ys) );
let union c1 c2 = (List.filter (fun x -> not (List.mem x c2)) c1) @ c2 in
Chars (Array.init (Array.length xs) (fun i -> union xs.(i) ys.(i)))
警告8:这种模式匹配是
,并不详尽。以下是一个未匹配的
a值示例:(chars _,
States _)
Warning 8: this pattern-matching is not exhaustive. Here is an example of a value that is not matched: (Chars _, States _)
您现在可以将建议的模式复制粘贴回代码中。这通常是我如何为具有数十个构造函数的类型生成非脆弱的catch-all模式。您可能需要多次启动编译器,但是它比自己输入更快。
You can now copy-paste the suggested pattern back into your code. This is usually how I generate non-fragile catch-all patterns for types with tens of constructors. You may need to launch the compiler several times, but it's still faster than typing them yourself.
这篇关于解决脆弱模式匹配的建议的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!