Alex Rivera | Logout

Suppress exhaustive matching warning in OCaml

Asked 2010-06-25T15:30:08.910
10

I'm having a problem in fixing a warning that OCaml compiler gives to me.

Basically I'm parsing an expression that can be composed by Bool, Int and Float.

I have a symbol table that tracks all the symbols declared with their type:

type ast_type = Bool | Int | Float
and variables = (string, int*ast_type) Hashtbl.t;

where int is the index used later in the array of all variables.

I have then a concrete type representing the value in a variable:

type value =
  | BOOL of bool
  | INT of int
  | FLOAT of float
  | UNSET
and var_values = value array

I'm trying to define the behaviour of a variable reference inside a boolean expression so what I do is

  • check that the variable is declared
  • check that the variable has type bool

to do this I have this code (s is the name of the variable):

| GVar s ->
            begin
                try
                    let (i,t) = Hashtbl.find variables s in
                        if (t != Bool) then
                            raise (SemanticException (BoolExpected,s))
                        else
                            (fun s -> let BOOL v = Array.get var_values i in v)
                with
                    Not_found -> raise (SemanticException (VarUndefined,s)) 
            end

The problem is that my checks assure that the element taken from var_values will be of type BOOL of bool but of course this constraint isn't seen by the compiler that warns me:

Warning P: this pattern-matching is not exhaustive. Here is an example of a value that is not matched: (FLOAT _ |INT _ |UNSET)

How am I supposed to solve this kind of issues? Thanks in advance

Edit
Report

1 Answer

8

This is a problem that you can solve using OCaml's polymorphic variants.

Here is some compilable OCaml code that I infer exhibits your problem:

type ast_type = Bool | Int | Float
and variables = (string, int*ast_type) Hashtbl.t

type value =
  | BOOL of bool
  | INT of int
  | FLOAT of float
  | UNSET

and var_values = value array

type expr = GVar of string

type exceptioninfo = BoolExpected | VarUndefined

exception SemanticException of exceptioninfo * string

let variables = Hashtbl.create 13

let var_values = Array.create 13 (BOOL false)

let f e = 
  match e with
  | GVar s ->
    begin
        try
        let (i,t) = Hashtbl.find variables s in
            if (t != Bool) then
            raise (SemanticException (BoolExpected,s))
            else
            (fun s -> let BOOL v = Array.get var_values i in v)
        with
        Not_found -> raise (SemanticException (VarUndefined,s)) 
    end

It generates the warning:

File "t.ml", line 30, characters 42-48:
Warning P: this pattern-matching is not exhaustive.
Here is an example of a value that is not matched:
(FLOAT _|INT _|UNSET)

Here is the same code transformed to use polymorphic variants. That code compiles without warnings. Note that polymorphic variants have more expressive power than standard types (here allowing to express that var_values is an array of BOOL only), but they can lead to puzzling warnings.

type ast_type = Bool | Int | Float
and variables = (string, int*ast_type) Hashtbl.t

type value =
  [ `BOOL of bool
  | `INT of int
  | `FLOAT of float
  | `UNSET ]

and var_values = value array

type expr = GVar of string

type exceptioninfo = BoolExpected | VarUndefined

exception SemanticException of exceptioninfo * string

let variables = Hashtbl.create 13

let var_valu
answered 2010-06-25T22:44:54.303

Your Answer