解决脆弱模式匹配的建议 [英] Suggestion for solving fragile pattern matching

查看:121
本文介绍了解决脆弱模式匹配的建议的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我经常需要匹配应该有相同构造函数的值的元组。总结 _,_ 总是结束。这当然是脆弱的,任何额外的构造函数添加到类型将编译得很好。我目前的想法是有连接第一个但不是第二个参数的匹配。但是,有没有其他选择?

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆