Proposal for dealing with fragile pattern matching

I often need to map a tuple of values ​​that must have the same constructor. Capture _,_always ends at the end. This is, of course, fragile, any additional constructor added to the type will compile fine. My current thoughts are to have matches that connect the first, but not the second argument. But are 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
+4
source share
3 answers

You can use a slightly shorter picture below:

| (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)))

8: . , : (Chars _, _)

- . - catch-all . , , , .

+8

( ), Obj, , . , a b :

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 *)
    | x, y when (Obj.tag (Obj.repr x)) <> (Obj.tag (Obj.repr y)) -> assert false

( , ).

EDIT: Obj, x y :

| x, y when x <> y -> assert false

, .

+1

/, , , , " " . , "" , .

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)))
  | States _, _ -> assert false

  | 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)))
  | Chars _, _ -> assert false
+1

Source: https://habr.com/ru/post/1017225/


All Articles