nlu*_*oni 4 ocaml functional-programming pattern-matching
我经常需要匹配应该具有相同构造函数的元组元组.最后,笼子_,_总是炙手可热.这当然是脆弱的,添加到该类型的任何其他构造函数将完全编译.我目前的想法是连接第一个但不是第二个参数的匹配.但是,还有其他选择吗?
例如,
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
Run Code Online (Sandbox Code Playgroud)
您可以使用下面稍短的图案:
| (Chars _| States _), _ -> assert false
Run Code Online (Sandbox Code Playgroud)
实际上,你可以让编译器为你生成它,因为它仍然有点乏味.输入以下内容并编译:
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)))
Run Code Online (Sandbox Code Playgroud)
警告8:此模式匹配并非详尽无遗.以下是不匹配的值的示例:(Chars _,States _)
您现在可以将建议的模式复制粘贴回代码中.这通常是我为具有数十个构造函数的类型生成非脆弱的catch-all模式的方法.您可能需要多次启动编译器,但它仍然比自己键入它们更快.