functional-programming - 解决脆弱模式匹配的建议

标签 functional-programming pattern-matching ocaml

我经常需要匹配应该具有相同构造函数的值元组。大杂烩_,_总是在最后结束。这当然是脆弱的,任何添加到该类型的额外构造函数都可以很好地编译。我目前的想法是让匹配连接第一个但不连接第二个参数。但是,还有其他选择吗?

例如,

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

最佳答案

您可以使用下面稍短的模式:

| (Chars _| States _), _ -> assert false

其实你可以让编译器帮你生成,因为还是有点繁琐。
输入以下内容并编译:
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)))

Warning 8: this pattern-matching is not exhaustive. Here is an example of a value that is not matched: (Chars _, States _)



您现在可以将建议的模式复制粘贴回您的代码中。这通常是我为具有数十个构造函数的类型生成非脆弱的全能模式的方式。您可能需要多次启动编译器,但它仍然比自己键入它们要快。

关于functional-programming - 解决脆弱模式匹配的建议,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4346901/

相关文章:

ocaml - 开始 Ocaml - 返回未实现的测试用例

clojure - 在 Clojure 中声明匿名函数是否很昂贵?

Scala:以值为条件的隐式类型转换

java - 字符串匹配不适用于特殊字符 "/"

string - 字符串匹配的随机算法

types - 双重强制什么时候有用?

types - 如何在 OCaml 中制作使用电池的 Dyn_array 的类型?

c# - 如何在列表和字典之间进行左连接?

list - 在 Haskell 中合并两个列表

programming-languages - 为什么使用 Erlang 决定 "against"?