3
votes

Is there a way to pattern match against the just the constructor that is independent of constructor arity? Sometimes in a pattern match I only care about the constructor and not the data associated with it.

My concern is that when I change the arity of a constructor in an ADT, I have to go through and change all of my pattern matches, even ones that discard all the "fields" (what's the right term?) on the data constructor.

Suppose I have an ADT with multiple constructors

(* time * message *)
type log_message = 
    Warning of float * string
  | Error of float * string

and I want to inspect a value of this type, but only care about the constructor I have to write something like

let is_error_message x = match x with
    | Warning _, _ -> false
    | Error _, _ -> true

If later I want to go back and add a severity field to warning, giving me

type log_message =
   Warning of float * string * int
 | Error of float * string

I have to add a new wildcard to the pattern in is_error_message to satisfy the type checker.

let is_error_message x = match x with
    | Warning _, _, _ -> false
    | Error _, _ -> true
1

1 Answers

4
votes

The type definition

type log_message = 
  | Warning of float * string
  | Error of float * string

means that both constructors (Warning and Error) do not accept two arguments, but rather a product (i.e. tuple) of them. So you instatiate as follows:

Warning (4.0, "you better be warned")

When performing pattern matching on an instance of this variant, you could just use _ to specify a tuple of arbitrary length (if you don't care about the parameters passed to the constructor):

type log_message =
  | Warning of float * string
  | Error of float * string;;

let is_error_message x = match x with
  | Warning _ -> false
  | Error _ -> true;;

is_error_message (Warning (2.0, "totally not an error"));;
- : bool = false